View 支持内容移动的api
- scrollTo(int x, int y)相对初始位置滚动 x,y 距离。
- 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。
-
初始化
mScroller = new Scroller(context, new LinearInterpolator(), true);
-
设置滚动参数,开始计算,这是一个持续过程,持续时间为:duration
mScroller.startScroll(startX, startY, dx, dy,duration);
-
获取实时计算结果
float x = mScroller.getCurrX(); float y = mScroller.getCurrY();
-
判断是否结束
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();