利用Scroller实现自己的滑动布局

来源:互联网 发布:域名注册投资 编辑:程序博客网 时间:2024/05/20 05:06

这篇博客主要介绍如何借助Scroller来实现自己的ScrollerView。关于Scroller基本上只要知道两个函数基本上就差不多了!一个是scrollBy,一个是scrollTo,看这两个函数的名字,相信你也应该猜得出来这两个函数的不同之处!

scrollBy(int x ,int y)代表UI沿着X轴移动x距离,沿着Y轴移动y距离

scrollTo(int x,int y)代表UI沿着X轴移动到x位置,沿着Y轴移动到y位置

在计算UI移动的距离时,我们需要借助getScrollX和getScrollY来确定UI实际的移动距离,在进行边界判断的时候需要用到!

现在来看一下效果图:
这里写图片描述

基本的效果就是如上图所示,各个子view的点击事件没有添加,有兴趣的可以自己试一下,现在附上源码:

import android.content.Context;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.view.animation.AccelerateDecelerateInterpolator;import android.widget.Scroller;/** * Created by Administrator on 2017/9/9 0009. */public class ScrollViewGroup extends ViewGroup {    private int mViewCount;    private int mWidth;    private int mHeight;    private int mLeftBorder;    private int mRightBorder;    private Scroller mScroller;    private float mDown = 0.0f;    private float mLastDown = 0.0f;    private int mMinScroll = 8;    private float mMove;    public ScrollViewGroup(Context context) {        super(context);        init();    }    public ScrollViewGroup(Context context, AttributeSet attrs) {        super(context, attrs);        init();    }    private void init(){        mScroller = new Scroller(getContext());    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        mViewCount = getChildCount();        for (int i = 0; i<mViewCount;i++){            View view = getChildAt(i);            measureChild(view,widthMeasureSpec,heightMeasureSpec);        }        mWidth = MeasureSpec.getSize(widthMeasureSpec);        mHeight = MeasureSpec.getSize(heightMeasureSpec);        Log.i("zyq","mWidth = "+mWidth+",mHeight = "+mHeight);        setMeasuredDimension(mWidth,mHeight);    }    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        if(changed){            int width = 0;            for (int i = 0; i < mViewCount ; i ++){                View view = getChildAt(i);                view.layout(width,t,width+view.getMeasuredWidth(),t+view.getMeasuredHeight());                width += view.getMeasuredWidth();            }            mLeftBorder = getChildAt(0).getLeft();            mRightBorder = getChildAt(mViewCount-1).getRight();            Log.i("zyq","mLeftBorder = "+mLeftBorder+",mRightBorder = "+mRightBorder);        }    }    @Override    public boolean onInterceptTouchEvent(MotionEvent ev) {        switch (ev.getAction()){            case MotionEvent.ACTION_DOWN:                mDown = ev.getRawX();                mLastDown = mDown;                break;            case MotionEvent.ACTION_MOVE:                mMove = ev.getRawX();                float diff = Math.abs(mMove-mDown);                if(diff > mMinScroll){                    return true;                }                break;        }        return super.onInterceptTouchEvent(ev);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        switch (event.getAction()){            case MotionEvent.ACTION_DOWN:                mDown = event.getRawX();                mLastDown = mDown;                return true;            case MotionEvent.ACTION_MOVE:                mMove = event.getRawX();                int dis = (int) (mLastDown - mMove);                if(getScrollX() + dis <=mLeftBorder){                    dis = 0;                }                if(getScrollX() + mWidth + dis >= mRightBorder){                    dis = 0;                }                Log.i("zyq","getScrollX = "+getScrollX()+",mWidth = "+mWidth);                scrollBy(dis,0);                mLastDown = mMove;                break;            case MotionEvent.ACTION_UP:                int disOffset = getScrollX();                if(disOffset >= mRightBorder){                    scrollTo(mRightBorder-mWidth,0);                    return true;                }                int index = (disOffset+mWidth/2)/mWidth;                scrollTo(index*mWidth,0);                break;        }        return true;    }    @Override    public void computeScroll() {        if (mScroller.computeScrollOffset()){            scrollTo(mScroller.getCurrX(),mScroller.getCurrY());            invalidate();        }    }}

在Scroller的构造方法中,我们可以传入一个插值器,如果没有指定的话,系统会默认给我们创建的Scroller建立一个插值器(ViscousFluidInterpolator),有兴趣的可以自行改变插值器看看效果!!

基本上代码都是我之前讲的东西,在这里就不重复,这里使用了事件拦截,不明白的朋友可以查看我前几篇博客中写的浅谈android 点击事件分发处理流程,这里也不详细描述了,在整个代码中可以说使用if语句就是进行边界判断的,不清楚的话可以自行添加log,打印参数出来看看!!!

关于利用Scroller实现自己的滑动布局就说到这里,有兴趣的朋友可以关注我一下,有什么问题可以大家一起讨论!!!

阅读全文
0 0
原创粉丝点击