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

来源:互联网 发布:黑莓playbook软件下载 编辑:程序博客网 时间:2024/05/16 12:50

今天给大家分享一个使用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<cCount;i++){            View childView = this.getChildAt(i);            /*测量每一个子View*/            measureChild(childView,widthMeasureSpec,heightMeasureSpec);        }    }    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        if(changed){            int cCount = this.getChildCount();            for (int i=0;i<cCount;i++){                View childView = this.getChildAt(i);                /*从上往下布局*/                childView.layout(0,i*childView.getMeasuredHeight(),childView.getMeasuredWidth(),(i+1)*childView.getMeasuredHeight());            }            mTopBorder = this.getChildAt(0).getTop();            mBottomBorder = this.getChildAt(this.getChildCount()-1).getBottom();        }    }    @Override    public boolean onInterceptTouchEvent(MotionEvent ev) {        switch (ev.getAction()){            case MotionEvent.ACTION_DOWN:                mYDown = ev.getRawY();                mLastMove = mYDown;                break;            case MotionEvent.ACTION_MOVE:                mYMove = ev.getRawY();                int diff = (int) Math.abs(mYMove - mYDown);                if(diff > 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)

<?xml version="1.0" encoding="utf-8"?><g.scrolltest.view.VDViewPager xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/ll"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="g.scrolltest.MainActivity">    <Button        android:layout_width="match_parent"        android:layout_height="match_parent"        android:text="One"/>    <Button        android:layout_width="match_parent"        android:layout_height="match_parent"        android:text="Two"/>    <Button        android:layout_width="match_parent"        android:layout_height="match_parent"        android:text="Three"/></g.scrolltest.view.VDViewPager>

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


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);    }}

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


0 0
原创粉丝点击