浅探OverScroller
来源:互联网 发布:java工程师发展前景 编辑:程序博客网 时间:2024/04/30 01:14
最近有点儿纠结listview是怎么实现滑翔运行的(也就是抛出之后,自行滑动一段时间),一开始我以为用到了什么高大上的算法,于是想从源码中查找,结果没发现,不过反而让我发现了一点点新东西。
if (mFlingRunnable == null) { mFlingRunnable = new FlingRunnable(); }然后我就对FlingRunnable这个类产生了点兴趣,看看是这样的。
FlingRunnable() { mScroller = new OverScroller(getContext()); }一看是用到了OverScroller这个类,之后有某处会调用这个方法
void start(int initialVelocity) { // 省略 mScroller.fling(0, initialY, 0, initialVelocity, 0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE); // 省略 }因此,我就猜测,类似于滑翔运动是基础OverScroller并且与fling这个方法有关,
对于这个方法,是这样介绍的
/** * Start scrolling based on a fling gesture. The distance traveled will * depend on the initial velocity of the fling. * * @param startX Starting point of the scroll (X) * @param startY Starting point of the scroll (Y) * @param velocityX Initial velocity of the fling (X) measured in pixels per * second. * @param velocityY Initial velocity of the fling (Y) measured in pixels per * second * @param minX Minimum X value. The scroller will not scroll past this point * unless overX > 0. If overfling is allowed, it will use minX as * a springback boundary. * @param maxX Maximum X value. The scroller will not scroll past this point * unless overX > 0. If overfling is allowed, it will use maxX as * a springback boundary. * @param minY Minimum Y value. The scroller will not scroll past this point * unless overY > 0. If overfling is allowed, it will use minY as * a springback boundary. * @param maxY Maximum Y value. The scroller will not scroll past this point * unless overY > 0. If overfling is allowed, it will use maxY as * a springback boundary.因为是listview,不存在x方向上的变化,因此跟x有关的参数都变成0了
一般来说,因为速度上是有方向的,但在这里可以看到
* @param minY Minimum Y value. The scroller will not scroll past this point * unless overY > 0. If overfling is allowed, it will use minY as * a springback boundary.
意思是,滚轴不会滚过这一点,除非overY>0,如果允许overfling,它将会使用minY作为回弹边界。
这在这里,一般情况下,minY都会被设置为0,也就是说,速度方向为负数的情况,只能得到为0的滑动距离。
至于解决方案,在下方讲解会说明。
为了测试滑翔运动是不是用这个类来解决,本博主模仿了一下,并且得到一些数据。
本例子也是基于listview实现的,是为了更加准确的验证滑动距离,还有数据的变化会不会随着listview的停止而停止。
初始的时候,需要有一个手势来获取抛出的速度
private GestureDetector mGestureDetector;并且要在构造器实现
mGestureDetector = new GestureDetector(context,new MyOnGestureListener());
class MyOnGestureListener extends GestureDetector.SimpleOnGestureListener{ @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { return false; } }
手势要能生效,这个步骤是必不可缺的。
@Override public boolean onTouchEvent(MotionEvent ev) { mGestureDetector.onTouchEvent(ev); return super.onTouchEvent(ev); }
之后写了一个类,实现Runnable
private class FlingScroller implements Runnable{ OverScroller mFlingScroller; boolean isRunning; public FlingScroller(){ mFlingScroller = new OverScroller(getContext()); }
<span style="white-space:pre"></span>private void postExecute() { if (isRunning) post(this); } private void start(){ isRunning = true; postExecute(); }
void withFling( int velocityY) { int initialY = velocityY < 0 ? Integer.MAX_VALUE : 0; mFlingScroller.fling(0,initialY,0,velocityY,0, Integer.MAX_VALUE,0,Integer.MAX_VALUE); }在这个方法,用来传入一开始的y方向上的速度
如果速度<0,让他的初始值为int的最大值,否则为0
上面调用post(this)后,会执行:
@Override public void run() { boolean endAnima = true; if (mFlingScroller.computeScrollOffset()){ final int startY = mFlingScroller.getStartY(); int currY = startY==Integer.MAX_VALUE ?Integer.MAX_VALUE-mFlingScroller.getCurrY():mFlingScroller.getCurrY(); Log.d("FlingScroller", "currY:" + currY); endAnima = false; } if (!endAnima){ postExecute(); }else { isRunning = false; } }
分析这个:
if (mFlingScroller.computeScrollOffset()){ final int startY = mFlingScroller.getStartY(); int currY = startY==Integer.MAX_VALUE ?Integer.MAX_VALUE-mFlingScroller.getCurrY():mFlingScroller.getCurrY(); Log.d("FlingScroller", "currY:" + currY); endAnima = false; }
startY是获取一开始的initialY值,currY也是根据startY来计算的,因为手势向上滑动时(屏幕向下滚动),初速度为负,当前位置也不断变小,因此用Integer的最大值减去当前位置,可以获取正确的当前位置。
根据这段做一下测试,用最大速度抛出滑动
if (mFlingScroller.computeScrollOffset()){ final int startY = mFlingScroller.getStartY(); int currY = startY==Integer.MAX_VALUE ?Integer.MAX_VALUE-mFlingScroller.getCurrY():mFlingScroller.getCurrY(); Log.d("FlingScroller", "currY:" + currY); endAnima = false; }开头一部分:
10-03 01:24:23.654 18887-18887/com.test.measurelistviewofsliding D/FlingScroller: currY:16010-03 01:24:23.674 18887-18887/com.test.measurelistviewofsliding D/FlingScroller: currY:48010-03 01:24:23.698 18887-18887/com.test.measurelistviewofsliding D/FlingScroller: currY:84710-03 01:24:23.722 18887-18887/com.test.measurelistviewofsliding D/FlingScroller: currY:124310-03 01:24:23.750 18887-18887/com.test.measurelistviewofsliding D/FlingScroller: currY:163710-03 01:24:23.774 18887-18887/com.test.measurelistviewofsliding D/FlingScroller: currY:204210-03 01:24:23.802 18887-18887/com.test.measurelistviewofsliding D/FlingScroller: currY:2441
中间一部分:
10-03 01:24:24.374 18887-18887/com.test.measurelistviewofsliding D/FlingScroller: currY:914910-03 01:24:24.402 18887-18887/com.test.measurelistviewofsliding D/FlingScroller: currY:935610-03 01:24:24.422 18887-18887/com.test.measurelistviewofsliding D/FlingScroller: currY:954110-03 01:24:24.454 18887-18887/com.test.measurelistviewofsliding D/FlingScroller: currY:974310-03 01:24:24.526 18887-18887/com.test.measurelistviewofsliding D/FlingScroller: currY:1026010-03 01:24:24.550 18887-18887/com.test.measurelistviewofsliding D/FlingScroller: currY:10417
结尾一部分:
10-03 01:24:26.054 18887-18887/com.test.measurelistviewofsliding D/FlingScroller: currY:1435010-03 01:24:26.078 18887-18887/com.test.measurelistviewofsliding D/FlingScroller: currY:1435610-03 01:24:26.102 18887-18887/com.test.measurelistviewofsliding D/FlingScroller: currY:1436210-03 01:24:26.126 18887-18887/com.test.measurelistviewofsliding D/FlingScroller: currY:1436610-03 01:24:26.154 18887-18887/com.test.measurelistviewofsliding D/FlingScroller: currY:1436910-03 01:24:26.178 18887-18887/com.test.measurelistviewofsliding D/FlingScroller: currY:1437110-03 01:24:26.202 18887-18887/com.test.measurelistviewofsliding D/FlingScroller: currY:1437210-03 01:24:26.226 18887-18887/com.test.measurelistviewofsliding D/FlingScroller: currY:14372
得出结论,一开始速度一直增加,中间时候速度匀速,结尾时速度开始减小至0.
OverScroller还有一个比较重要的方法。
/** * The amount of friction applied to flings. The default value * is {@link ViewConfiguration#getScrollFriction}. * * @param friction A scalar dimension-less value representing the coefficient of * friction. */ public final void setFriction(float friction) { mScrollerX.setFriction(friction); mScrollerY.setFriction(friction); }
这个参数是用来设置摩擦系数的,根据api的说明,默认值为ViewConfiguration.getScrolFriction。即:
public static float getScrollFriction() { return SCROLL_FRICTION; }
/** * The coefficient of friction applied to flings/scrolls. */ private static final float SCROLL_FRICTION = 0.015f;
默认值为0.015f。
源码下载:https://github.com/q742972035/measurelistviewofsliding
1 0
- 浅探OverScroller
- OverScroller.springBack的解释
- android scroller overscroller用法
- android scroller overscroller用法
- Android 初探OverScroller
- Android Scroller OverScroller使用
- 触摸[6] OverScroller
- OverScroller类和Scroller类
- android view滑动助手类OverScroller
- Android Scroll详解(二):OverScroller实战
- android view滑动助手类OverScroller
- View的scrollTo(),scrollBy()以及Scroller,OverScroller
- Android Scroll详解(二):OverScroller实战
- android view滑动助手类 OverScroller VelocityTracker
- Android7.0中文文档(API)-- OverScroller
- android view滑动助手类OverScroller
- 关于OverScroller.startScroll函数失效的解决办法
- OverScroller、VelocityTracker、ViewConfiguration综合使用达到炫酷效果
- windows编程中L,_T() ,TEXT和_TEXT的使用及其区别
- 使用javamail发送验证邮件
- 同余意义下的高斯消元解决几类常见的问题+例题
- 单张纹理的Shader
- 移动应用框架 ionic2 自学须知的基本知识点
- 浅探OverScroller
- 【暂无】 堆 合并果子(fruit.cpp)
- 第六周项目一 建立顺序环形队列算法库
- HDU java版——1175连连看 ,MLE,跪求大神指教!!
- Hadoop之——Hadoop2.5.2 HA高可靠性集群搭建(Hadoop+Zookeeper)前期准备
- 连续概率(概率,uva 11346)
- 指之舞:颈椎
- 庞大触角加精准定向,Facebook如何主导2016美国总统大选
- 高斯滤波及高斯卷积核C++实现