自定义类似于ViewPager的可上下滑动切换效果的视图

今天给大家分享一个使用Scroller滚动类实现的控件,我们知道,viewpager实现的是一种左右切换的效果,使用scroller+事件分发来实现viewpager本身并不是一件特别难的事,因为viewpager其内部的实现原理就是这样。为了跟大家更好地分享下scroller的用法,我实现了一个可以上下切换的效果。下面直接贴该类代码:

1.VDViewPager.class

import android.content.Context;
import android.support.v4.view.ViewConfigurationCompat;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.Scroller;

/**
 * Created by _H_JY on 2016/3/3.
 * instruction:A custom viewpager which srcolls to vertical direction.
 */

public class VDViewPager extends ViewGroup{

    /*滚动实例*/
    private Scroller mScroller;

    /*判断是否滑动的最小距离*/
    private int mTouchSlop;

    /*手指触摸到屏幕时y值*/
    private float mYDown;

    /*手指在竖直方向上移动的距离*/
    private float mYMove;

    /*标记最后的位置*/
    private float mLastMove;

    /*标记上边缘*/
    private int mTopBorder;

    /*标记下边缘*/
    private int mBottomBorder;

    public VDViewPager(Context context) {
        this(context, null);
    }

    public VDViewPager(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public VDViewPager(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        /*初始化滚动实例*/
        mScroller = new Scroller(context);

        /*获取最小滑动值,该值用于判断是否可滑*/
        ViewConfiguration vc = ViewConfiguration.get(context);
        mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(vc);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int cCount = this.getChildCount();
        for (int i=0;i mTouchSlop){ //判断是否可滑
                    return true;
                }
                mLastMove = mYMove;
                break;
            default:
                break;
        }

        return super.onInterceptTouchEvent(ev);
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()){
            case MotionEvent.ACTION_MOVE:
                mYMove = event.getRawY();
                int scrolledY = (int) (mLastMove - mYMove);
                if(this.getScrollY() + scrolledY < mTopBorder){
                    /*到第一个子View顶端时不给下滑*/
                    this.scrollTo(mTopBorder,0);
                    return true;
                }else if(this.getScrollY() + scrolledY + this.getHeight() > mBottomBorder){
                    /*到最后一个子View底端时不给上滑*/
                    this.scrollTo(0,mButtomBorder - this.getHeight());
                    return true;
                }
                this.scrollBy(0,scrolledY);
                mLastMove = mYMove;
                break;
            case MotionEvent.ACTION_UP:
                int targetIndex = (this.getScrollY()+this.getHeight()/2)/this.getHeight();
                /*得到应该滑动的距离*/
                int dy = targetIndex*this.getHeight() - this.getScrollY();
                /*开始滑动*/
                mScroller.startScroll(0,this.getScrollY(),0,dy);
                invalidate();
                break;
            default:
                break;
        }
        return super.onTouchEvent(event);
    }


    @Override
    public void computeScroll() {
        super.computeScroll();
        /*平滑滚动*/
        if(mScroller.computeScrollOffset()){
            this.scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
            invalidate();
        }
    }
}

上面的注释写得也比较清晰了,相信大家都能看懂。



2.布局文件(activity_main.xml)





    

布局文件相当简单,就三个按钮,没什么好说的额。。。


3.MainActivity.class(主Activity)

import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

    }


}

啥都没写,更不用说。。。运行效果图就不贴了。哈哈我太懒了


你可能感兴趣的:(Android开发)