OverScroller的使用 自定义一个ScrollView

Posted 怪兽N

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OverScroller的使用 自定义一个ScrollView相关的知识,希望对你有一定的参考价值。

1 简介

本文主要介绍OverScroller的使用。而本文示例演示综合使用OverScroller和EdgeEffect来实现自定义ScrollerView。OverScroller的基本使用与Scroller的使用非常类似,官方推荐使用OverScroller代替Scroller。
关于使用OverScroller还是像Scroller那样,三个步骤:定义滚动,触发滚动,然后不断更新滚动。具体看Scroller的使用这篇文章。

git项目: https://gitee.com/guaishoun/over_scroller_edge_effect.git

2 OverScroller比Scroller多的方法

对比Scroller,OverScroller有一些新方法如下

springBack方法

/**
* 这个方法用于弹回指定的X Y设定的区间内,使回滚动作有平滑过渡的感觉
* startX 、startY: x y起始值
* minX maxX: x回弹的区间(不再这个区间会回弹)
* minY maxY: y回弹的区间(不再这个区间会回弹)
* 返回值:true-->发生回弹,false-->startX、startY已经在指定区间,没有产生回弹动作
*/
public boolean springBack(int startX, int startY, int minX, int maxX, int minY, int maxY)

notifyHorizontalEdgeReached方法

notifyVerticalEdgeReached方法

//本文代码示例搞了挺久也没用上,大写尴尬。不怎么懂用,可以忽略
/**
* 通知OverScroller已经到达指定区域了,主要在没办法准确计算文时调用。
* startX 起始X
* finalX 期望终止位置
* overX 可浮动值
*/
public void notifyHorizontalEdgeReached(int startX, int finalX, int overX) {
    ...
}
public void notifyVerticalEdgeReached(int startY, int finalY, int overY) {
	...
}

3效果实例中OverScroller的使用

首先,初始化

public OverScrollerEdgeEffectView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        mScroller = new OverScroller(context);
		...
    }

然后在onTouchEvent中获取滑动速度

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getAction()&MotionEvent.ACTION_MASK;
        ...
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                if(velocityTracker==null){
                    velocityTracker = VelocityTracker.obtain();
                }else{
                    velocityTracker.clear();
                }
                velocityTracker.addMovement(event);
				...
                break;
            case MotionEvent.ACTION_MOVE:
                velocityTracker.addMovement(event);
                velocityTracker.computeCurrentVelocity(1000,mMaximumVelocity);
				....
                break;
            case MotionEvent.ACTION_UP:
                //计算
                velocityTracker.addMovement(event);
                velocityTracker.computeCurrentVelocity(1000,mMaximumVelocity);
                float vu = event.getY() - preMotion.getY();
                float velocityY = velocityTracker.getYVelocity();
                
                //TODO 使用速度fling 
                if(Math.abs(velocityY)>mMinimumVelocity){
                    mScroller.fling(0,getScrollY()-(int)vu,0,-(int)velocityY,
                                    0,0,0,containHeight-getHeight(),0,400);
                }
				
                //TODO 判断不在边界内回弹到边界内
                if(getScrollY() < 0 || getScrollY()+getHeight() > containHeight){
                    mScroller.springBack(0,getScrollY(),0,getWidth(),0, containHeight-getHeight());
                }
				...
                break;
            default:
                break;    
        }
        ...
    }

最后不断计算更新

    @Override
    public void computeScroll() {
        if (mScroller.computeScrollOffset()) {
            int y = mScroller.getCurrY();
            scrollTo(0,y);
            postInvalidateOnAnimation();
        }
    }

4总结

跟Scroller差不多,要跟EdgeEffect、Fling、Spring这些效果结合起来使用才有意思

以上是关于OverScroller的使用 自定义一个ScrollView的主要内容,如果未能解决你的问题,请参考以下文章

Android View视图系统分析和Scroller和OverScroller分析

树组件上的 Flex 4 自定义滚动条

Scroller的使用 仿ViewPager效果

如何在 tailwindcss 中为 plugin.withOptions 使用 theme()

如何滚动到长 ScrollView 布局的顶部?

咸鱼教程EUI多图片滑动组件ScrollView