zoukankan      html  css  js  c++  java
  • Android之自己定义(上方标题随ViewPager手势慢慢滑动)

    近期非常蛋疼,项目要模仿网易新闻的样式去做。上次把仿网易新闻client的下拉刷新写出来了。这次是ViewPager的滑动,同一时候ViewPager的上面标题下划线尾随者移动。本来通过ViewPager的OnPagerChangeListener的监听事件就能够完毕,可是做出来之后,由于须要一直的刷新,所以非常卡。一气之下。呵呵。自己全然的画了。整个点击事件,滑动事件都自己处理了。

    效果图例如以下:
     
     
    下标的长宽是随之改变的。
    使用方式:
    我的布局文件:
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        >
     
     
        <com.flyme.columnhorizontalscrollview.ColumnHorizontalScrollView 
            android:layout_width="match_parent"
            android:paddingLeft="20dip"
            android:paddingRight="20dip"
            android:layout_height="100dip"
            android:id="@+id/title"
            />
        
        <android.support.v4.view.ViewPager
            android:background="@android:color/holo_orange_light"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/viewpager"
            />
        
    </LinearLayout>  
    非常easy。把自己定义的布局放在ViewPager的上面,非常任意了。你想放哪就放哪。
     
    在Activity中的使用方式为:
     
    ViewPager mViewPager = (ViewPager) findViewById(R.id.viewpager);
            ColumnHorizontalScrollView title = (ColumnHorizontalScrollView) findViewById(R.id.title);
            mViewPager.setAdapter(new FragmentStatePagerAdapter(getSupportFragmentManager()) {
                @Override
                public int getCount() {
                    return 10;
                }
                
                @Override
                public Fragment getItem(int arg0) {
                    return new MyFragment(arg0);
                }
            });
            title.setTitle("上市的公司","历史","游戏啊","房产证","精选的搞笑片段","段子","电脑硬件","热点","轻松一刻","时尚");  //这个是设置标题的  
     
            title.setspace(40);
            title.setViewPager(mViewPager);  //这个是将ViewPager对象给自己定义的View
     
    我就把自己定义的类代码贴出来吧:比較懒了,时间比較紧。代码封装的不好,也没怎么封装。见谅。
    public class ColumnHorizontalScrollView extends View implements OnPageChangeListener {
     
        private Context context;
        private int width ;
        private int padingLeft;
        private int padingRight ; 
        private float lineStartX = 0  ;
        private float lineEndX = 0  ;
        private Paint textPaint;
        private int textWidth ;
        private int lastPosition = 0 ;
        private float lineScale = 0 ; 
        
        private ViewPager mViewPager ;
        
        
        /**
         * 这些事默认设置的
         */
        private static final int DEFULT_TEXT_COLOR = Color.BLACK;
        private static final int DEFULT_TEXT_SIZE = 40;
        private  static final int DEFULT_LINE_COLOR = Color.RED;
        private static final int DEFULT_LINE_STRO = 5;
        
        
        private String [] str ; // 存储 题要显示的字符
        private float [] strX ; // 存储 每一个字符  開始的X位置
        private float [] strWidth ;  // 存储每一个字符的长度
        private int startX; // 与手势相关    记录按下的X的坐标
        
        private int recordDownX = 0 ;
        
        private OnClickOneListener mOnClickOneListener ;
        private OverScroller mScroller; 
     
        public ColumnHorizontalScrollView(Context context, AttributeSet attrs,
                int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init(context);
        }
        
        public ColumnHorizontalScrollView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init(context);
        }
        public ColumnHorizontalScrollView(Context context) {
            super(context);
            init(context);
        }
        
        
        /**
         * 初始化的时候须要new出来的一些类,和必要的设置
         * @param context
         */
        private void init(Context context){
            this.context = context ;
            mScroller = new OverScroller(context,new LinearInterpolator());
            textPaint = new Paint();
            linePaint = new Paint();
            
            textPaint.setColor(DEFULT_TEXT_COLOR);
            textPaint.setTextSize(DEFULT_TEXT_SIZE);
            textPaint.setTypeface(Typeface.SANS_SERIF);
            
            linePaint.setColor(DEFULT_LINE_COLOR);
            linePaint.setStrokeWidth(DEFULT_LINE_STRO);
        }
        
        
        
        
        /**
         * 绘图
         */
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            if (str == null) {
                return ;
            }
            measureSize();
            drawText(canvas); //画字
            measureLineSize();//測量下划线的位置
            drawLine(canvas);//画下划线
        }
        
        
        
        /**
         * 这个是用来通过Scroller来控制缓冲变化的   后来不须要了
         */
        @Override
        public void computeScroll() {
            if (mScroller.computeScrollOffset()) {
                scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            }
            super.computeScroll();
            postInvalidate();
        }
        
        
        /**
         * 画字的详细代码
         * @param canvas
         */
        private  void drawText(Canvas canvas){
            int totel = 0 ;
            for (int i = 0; i < str.length; i++) {
                if (i == 0 ) {
                    totel += padingLeft;
                }
                strX[i] = totel ;
                canvas.drawText(str[i], strX[i], textHeight, textPaint);
                float oneTextWidth = textPaint.measureText(str[i]);
                totel =(int) (totel +  oneTextWidth +space);
                strWidth[i] = oneTextWidth ;
            }
            textWidth = totel - space  +padingLeft ;
        }
        
        
        private void drawLine(Canvas canvas){
            canvas.drawLine(lineStartX, lineHeight ,lineEndX , lineHeight, linePaint);
        }
        
        
        
        private void measureSize(){
            width = getWidth();
            height = getHeight();
            padingLeft = getPaddingLeft();
            padingRight = getPaddingRight();
            textHeight = (int) (height / 2 - (textPaint.descent() + textPaint.ascent())/2); 
            lineHeight = (int) (textHeight - (textPaint.descent() + textPaint.ascent()));
        }
        
        
        
        private void measureLineSize(){
            lineStartX = strX[lastPosition] - space / 2 + (strWidth[lastPosition] + space )* lineScale;
            if ((lastPosition + 1) == mViewPager.getAdapter().getCount()) {
                lineEndX = strX[lastPosition] + strWidth[lastPosition] + space / 2 ;          
            }else {
                lineEndX = strX[lastPosition] + strWidth[lastPosition] + space / 2 + ( strWidth[lastPosition + 1] + space ) * lineScale;          
            }
        }
        
        
        
        public void setTitle(String ...str){
            this.str = str ;
            strX = new float[str.length];
            strWidth = new float[str.length];
        }
        
        
        private int space = 0 ;
        private Paint linePaint;
        private int lineHeight;
        private int height;
        private int textHeight;
        
        public void setspace(int space){
            this.space = space ;
        }
        
        public void setTextColorResourceId(int colorid){
            int color = context.getResources().getColor(colorid);
            textPaint.setColor(color);
        }
        
        public void setTextColor(int color){
            textPaint.setColor(color);
        }
        
        
        
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                startX = recordDownX = (int) event.getX();
                break;
            case MotionEvent.ACTION_MOVE:
                int moveX = (int) event.getX();
                int scrollX = getScrollX();
                if (Math.abs(moveX - recordDownX ) > 32 ) {
                    smootMove(scrollX , startX - moveX);
                }
                startX = (int) event.getX();
                break;
            case MotionEvent.ACTION_UP:
                int upX = (int) event.getX();
                if (Math.abs(upX - recordDownX ) < 32 ) {
                    int position = decidePosition(upX);
                    setPosition(position);
                    if (mOnClickOneListener != null) {
                        mOnClickOneListener.onClick(position) ;
                    }
                }
                break;
            }
            return true;
        }
        
        
        private int  decidePosition(int upX){
            for (int i = 0; i < strX.length; i++) {
                if ((upX + getScrollX()) < (strX[i] + strWidth[i]) + space / 2) {
                    return i ;
                }
            }
            return 0 ;
        }
        
        
        public void setPosition(int position){
    //        lastPosition = position ;
    //        int scrollX = getScrollX();
    //        int location = (int) (strX[lastPosition] - space - 20);
    //        int dy = (int)(location  - getScrollX());
    //        if ((location + width) > (textWidth + padingRight ) ) {
    //            mScroller.startScroll(scrollX, 0,textWidth + padingRight - width - getScrollX()  , 0, 200);
    //        }else {
    //            mScroller.startScroll(scrollX, 0, dy , 0, 200);
    //        }
    //        if ((scrollX + dy ) > (textWidth+padingRight - width)) {
    //            mScroller.startScroll(scrollX, 0, textWidth+padingRight - width - scrollX , 0, 200);
    //        }else {
    //            mScroller.startScroll(scrollX, 0, dy , 0, 200);
    //        }
            mViewPager.setCurrentItem(position);
        }
        
        
        private void smootMove(int scrollX , int dy){
            if ((scrollX <= 0 && dy > 0 && textWidth > width)  || (scrollX > 0)) {
                if ((scrollX + dy) < 0 ) {
                    scrollTo(0 , 0);
                }else {
                    if ((scrollX + dy + getWidth()) > (textWidth+padingRight )) {
                        scrollTo(textWidth +padingRight - getWidth() , 0);
                    }else {
                        scrollTo(scrollX + dy , 0);
                    }
                }
            }
        }
        
        public void setViewPager(ViewPager mViewPager){
            this.mViewPager = mViewPager;
            if (this.mViewPager != null) {
                this.mViewPager.setOnPageChangeListener(this);
            }
        }
        
        /**
         * dip转为 px
         */
        public int dip2px(float dipValue) {
            final float scale = context.getResources().getDisplayMetrics().density;
            return (int) (dipValue * scale + 0.5f);
        }
     
        @Override
        public void onPageScrollStateChanged(int arg0) {
            
        }
     
        @Override
        public void onPageScrolled(int lastPosition, float scale, int location) {
            this.lastPosition = lastPosition ;
            lineScale = scale ;
            invalidate();
            smootMove((int)(strX[lastPosition] - space - 20 ) ,(int)((strWidth[lastPosition] + space )*  lineScale));
        }
     
        @Override
        public void onPageSelected(int arg0) {
        }
        
        
        public void setOnClickOneListener (OnClickOneListener mOnClickOneListener){
            this.mOnClickOneListener = mOnClickOneListener ;
        }
        
        
        /**
         * 内部接口    是点击事件的接口
         * @author lenovo
         *
         */
        interface OnClickOneListener{
            public void onClick(int position);
        }
        
    }  
     
    over。
    关于bug:
    这个做的还不是非常完好。另一些东西没有做适配。

    假设有人用,在使用过程中出现故障,你能够自己做一下简单的适配。

     
     
    源代码下载地址: 

    http://pan.baidu.com/s/1sj0lIxR


     
    我的github地址:https://github.com/flyme2012
    我的博客园 博客地址:http://www.cnblogs.com/flyme2012/
  • 相关阅读:
    Max History CodeForces
    Buy a Ticket CodeForces
    AC日记——字符串的展开 openjudge 1.7 35
    AC日记——回文子串 openjudge 1.7 34
    AC日记——判断字符串是否为回文 openjudge 1.7 33
    AC日记——行程长度编码 openjudge 1.7 32
    AC日记——字符串P型编码 openjudge 1.7 31
    AC日记——字符环 openjudge 1.7 30
    AC日记——ISBN号码 openjudge 1.7 29
    AC日记——单词倒排 1.7 28
  • 原文地址:https://www.cnblogs.com/blfbuaa/p/7110538.html
Copyright © 2011-2022 走看看