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

    最近很蛋疼,项目要模仿网易新闻的样式去做。上次把仿网易新闻客户端的下拉刷新写出来了,这次是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>  
    很简单,把自定义的布局放在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/
  • 相关阅读:
    SQL Server 中的事务与事务隔离级别以及如何理解脏读, 未提交读,不可重复读和幻读产生的过程和原因
    微软BI 之SSIS 系列
    微软BI 之SSIS 系列
    微软BI 之SSIS 系列
    微软BI 之SSIS 系列
    微软BI 之SSIS 系列
    微软BI 之SSAS 系列
    微软BI 之SSRS 系列
    微软BI 之SSRS 系列
    配置 SQL Server Email 发送以及 Job 的 Notification通知功能
  • 原文地址:https://www.cnblogs.com/flyme2012/p/4092895.html
Copyright © 2011-2022 走看看