初级UI自定义View-view滑动

213 阅读2分钟

View 支持内容移动的api

  1. scrollTo(int x, int y)相对初始位置滚动 x,y 距离。
  2. scrollBy(int x, int y)相对当前位置滚动 x,y 距离。

scrollTo、scrollBy 的滚动是瞬间移动,没有过度,如过想要 ScrollView或者RecycleView 那样的滑动效果我们需要借助一些工具类

1. Scroller、OverScroller

Scroller 和 OverScroller 都是滚动辅助类,可以帮助我们计算滚动偏移量。这两个类api高度类似,Scroller 类出现的早(Android API 11),OverScroller 出现在API19 是 Scroller 的替代类,比 Scroller 多了几个 api。

  1. 初始化

    mScroller = new Scroller(context, new LinearInterpolator(), true);

  2. 设置滚动参数,开始计算,这是一个持续过程,持续时间为:duration

    mScroller.startScroll(startX, startY, dx, dy,duration);

  3. 获取实时计算结果

    float x = mScroller.getCurrX(); float y = mScroller.getCurrY();

  4. 判断是否结束

    boolean isRunning = mScroller.computeScrollOffset()

    或者:

    boolean isFinsish = mScroller.getFinalX() == x && mScroller.getFinalY() == y

Scroller 和 OverScroller 都是辅助计算工具,并不能对 View 有什么影响,要使View 内容滚动,我们还要搭配调用 View 的 api。

   //开始计算
   mScroller.startScroll(startX, startY, dx, dy,duration);
   //请求view重绘 ,draw()方法会回调 computeScroll()方法
   invalidate();
   
   @Overrided
   public void oncomputeScroll(){
        if (mScroller.computeScrollOffset()) {
            float x = mScroller.getCurrX();
            float y = mScroller.getCurrY();
            // 根据计算结果绘制内容
            drawChild(x,y);
            // 递归请求view 重绘直到计算结束。
            invalidate();
        }

   }
   
   

2. VelocityTracker

借助 mScroller.startScroll()方法实现的滑动类似ViewPage。如果要实现RecycleView 那样松手后以一个初速度继续滑动直至速度为0停止滑动。我们需要借助 VelocityTracker 这个工具类来帮助我们计算速度速率。

mVelocity = VelocityTracker.obtain()


override fun onTouchEvent(event: MotionEvent): Boolean {
    //绑定event
    mVelocity.addMovement(event)
    if (event.action == MotionEvent.ACTION_UP) {
        //根据已收集的点计算当前速度。
        mVelocity.computeCurrentVelocity(1000)
        //开始以一个初速度开始滚动
        mVelocity.fling(startX,startY,velocityX,velocityY, minX, maxX, minY, maxY)
        invalidate();
    }
    return true
}

@Overrided
public void oncomputeScroll(){
    if (mScroller.computeScrollOffset()) {
        float x = mScroller.getCurrX();
        float y = mScroller.getCurrY();
        // 根据计算结果绘制内容
        drawChild(x,y);
        // 递归请求view 重绘直到计算结束。
        invalidate();
    }

}


3. ViewConfiguration

这个类主要定义了UI中所使用到的标准常量,像超时、尺寸、距离,如果我们需要得到这些常量的数据,我们就可以通过这个类来获取

//获得触发移动事件的最短距离,如果小于这个距离就不触发移动控件
int mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
//获得允许执行一个fling手势动作的最大速度值
int mMaximumVelocity = ViewConfiguration.get(context).getScaledMaximumFlingVelocity();
//获得允许执行一个fling手势动作的最小速度值
int mMinimumVelocity = ViewConfiguration.get(context).getScaledMinimumFlingVelocity();