聊一聊播放器控制层的Scroll吧

从开始做android开发,一晃就两年十个月了, 算上实习的公司已经经历了三家公司, 不知道是巧合还是怎么
三家都是做跟视频有关系的. 今天的记录跟视频有关系但是关系不打,主要是讲视频的控制层.
现在回头想想之前做播放器控制层的时候,基本都是没有动过脑子的, 关于MotionEvent 也是一知半解,写出来的控制层的代码,
都是从网上搜索到的.然后我看了看几家公司的代码, 基本上大家都是雷同的…

下面贴出来一个 示范代码, 网上随处可见.
Paste_Image.png

反正这代码的逻辑就是算touch Down 下时的Event xy 坐标 然后看当前的Event 坐标 来判断用户 是做的什么操作,以及滑动了多少. 这段代码 大部分时间应该都是没问题的, 大家也都是这样做的.
但是在用户做一些特殊操作的时候 就会有问题.

我举个例子:

用户touch 到了屏幕中间,然后向右滑动, 然后滑动到最右面, 不要松手 往左滑动.再滑动到中间继续往左滑.
你就会发现touch事件有断层, 并且滑动距离与 视频进退的比例不好设定. (这点尤为突出)

这些缺点 以及一些不如意的地方, 由于我描述能力不行, 可能说的不是太清楚, 只有实际开发碰见过这些问题的同学才会明白我说的是什么..

之前自己也一直没有注意到这些细节上的问题, 偶尔的一次机会发现了这个体验问题, 决心要解决它,重新去搞一套比较舒服的Scroll 算法. 最后在烨哥+飞哥的共同帮助下,完成了一套暂时看起来还不错的Scroll算法, 所以写下了这篇文章来记录一下想法和实现.

以下是正文

首先 我们要明确一件事情,

当用户手指touch down 到屏幕的一瞬间, 整个滑动过程, 用户滑动距离与视频改变的时间的比例,就已经确认了, 不能再因为任何原因改变, 一直到用户手指离开屏幕.

timeline

看图

上面这条线是影片的时间线,
0 就是视频起点
d 就是影片的总长度
Y 当前currentPosition
下面这条线是用户touch点在屏幕上的位置线
p是触摸左侧X坐标
q 触摸右侧X坐标
X touchDown的X坐标

其中需要说明的是 这里有个小细节, 很多人算触摸界限的时候,都习惯性设置0 和 ScreenWidth. 但是其实真正使用的时候, 是没有人会从0开始滑 或者滑到屏幕最右面的, 除非你是测试.
所以 p 是设置的1个padding值,并不是 0, q 也不是ScreenWidth. 一般是ScreenWidth - padding.

这套代码的整体思想很简单, x(用户的触摸x坐标)随着用户的滑动不停的在改变, 我们要用x来算出相应的y(影片seek到的位置), 也就是一个二元一次方程. y = ax + b; 所以我们要来先算出 a 和 b的 值.

init
首先是一些常量的初始化, 注释也都有说明,大家自行理解一下.
leftTouch 就是手指x坐标离左面的值
rightTouch 是离右面的值.
touchRange 是总的触摸长度.
rightDuration 是影片剩余的时间.

接着上面的说, 我们既然要算出a 和 b, 那么就需要 得到两组合适的 xy 值 代入公式.
其中已经确定好的一组值 就是 X 和 Y 就是手指刚落下的时候 那一组. 我们需要做的就是找出另外一组x y 值.

情况其实只有四种

  1. 以屏幕触摸终点 对应影片的Duration.
  2. 以屏幕触摸中点 对应影片的Duration.
  3. 以屏幕触摸起点 对应影片的起点
  4. 以屏幕触摸中点 对应影片的起点

可以根据比较 x 与touchRange的比值 与 y 与duration的比值的大小,来确定具体使用哪种情况.
比较口头的来说,也是有四种情况, 可以涵盖全部情况

  1. 影片已经播放的时间 比较短, 触摸的位置特别靠右.
  2. 影片已经播放的时间 比较短, 触摸的位置靠右,但是不是特别靠右
  3. 影片已经播放的时间 比较长, 触摸的位置特别靠左,
  4. 影片已经播放的时间 比较长, 触摸的位置靠左,但是不是特别靠左

具体代码如下,也是最核心的代码.

code

这个地方如果理解起来有点困难, 可以画一些图来感受一下,就能明白为什么这样对应了.
得到 两组 xy 值以后, 代入二元一次方程, 算出 ab 以后就好说拉!

final

以上就是整套Scroll的代码和解析了, 实际跑起来的效果特别好! 顺滑无比! 怎么滑动都不会有断层,而且无论用户触摸在哪里开始滑动,
滑动距离与影片改变的时间都很舒服.

Share Comments