前两天有人留言问购物车模块有个需求是侧滑删除应该这么做,类似QQ消息侧滑删除,借此总结一下实现逻辑,事实上诸如动画平移的这种view位置移动效果有两种解决方案:
- view控件自身的移动
- ViewGroup移动内容,注意是移动ViewGroup的内容,而不是自身的移动
对于view控件自身的移动这很好理解,View动画、属性动画就好,而ViewGroup去移动其内容,实质上是就像ScrollView控件一样,比如说上述购物车模块适配器item的线性布局,是由两部分组成:
①前半部分是正常显示的item,宽度为match_parent,所以默认显示的时候item会占满width
②后半部分是删除的view,默认状态是看不到它的,
首先简要说一下侧滑功能是怎么实现的,在购物车模块的adapter中,将item的view传递给slidView类(自定义继承线性布局),slidView将这个viewaddView给前半部分的item控件上,这样这个slidView就有了侧滑删除按钮,再将slidView赋值给adapter的viewHolder,其余adapter中设置就跟普通适配器没有区别了,接下来说说slidView是如何将侧滑删除功能完成?
slidView中重写onTouchEvent事件,利用move获取到的point(x,y)坐标点计算出一系列的move值,让ViewGroup调用scrollTo移动其内容(child_view),但是scrollTo函数是瞬时完成的移动,没有连续的动画,所以看上去不连贯用户体验不好,比如这样的一个场景,用户滑动了1/2的位置或者稍微再多点,这时候我们应该将删除按钮完整显示出来,这时候直接强制显示出来不太好,有一个过场动画就完美了,这时候我们需要使用Scroller类来辅助完成,首先介绍Scroller的使用,然后提出Scroller类的一些疑惑:
使用步骤:首先当然是实例化一个Scroller对象,然后在onTouchEvent中调用Scroller.startScroll去滑动(之后要用invalidate去刷新UI),然后重写computerScroll,在这个函数里用Scroller.computeScrollOffset()判断滑动是否完成,未完成则在这里继续使用scrollTo(还要用invalidate刷新UI),大体上就是这样的流程,至于说demo百度一搜一大把,这里就不说了,下面来说说疑问
①:什么是Scroller?Scroller是辅助view滑动的一个封装计算类,它本身是不操作view的,也就是说它没有滑动view的能力,最终的滑动view操作都是在view类中,它来计算规划一个view应该以什么样的方式等等去滑动,而且computerScroll()函数也是view类中的
②:那么computerScroll()函数是滑动view的操作吗,它与Scroller类是什么关系,实际上computerScroll函数也没有操作滑动,本质上滑动都是ScrollTo和ScrollBy来完成的,它与Scroller类的逻辑关系应当是:Scroller类计算出一系列基础数据交给computerScroll()函数去调用,然后computerScroll()函数加工一下这些参数,这个时候这些参数全部保存在view类中,调用invalidate去刷新(重绘draw函数),在draw函数重绘的过程中自然就会取到这些参数,这样UI界面就被完美的呈现出来,而每次draw函数运行过程中,他会调用computerScroll函数,computerScroll()函数又会去调用Scroller类去计算滑动的数据,这样一整套流程就同步起来了,各项数据源源不断传送给view的draw去绘制,其实这也是view动画的实现原理(补间动画),这就是我为什么将这个view滑动放到动画的博客分类中原因,下篇文章来讲讲view动画的实现流程