今天看到某个订餐app中有一个折叠菜品详情的特效,看起来非常不错,反编译源码之后发现是使用ListView做的。
但是最近对RecyclerView这个控件情有独钟,于是就尝试着使用RecyclerView进行了实现。
记录一下:
对于普通列表样式的RecyclerView我们再熟悉不过了,Activity+Adapter。
如果需要实现刚才效果,我们需要一个特殊的Item的布局文件:
|
|
这个布局分为上下两块儿,title部分是折叠时候显示的内容,这里我们只定义了一个TextView,如果有特殊需求可以设定一个容器。
下面的layout_content是展开时候所显示的布局,如果不考虑动画的情况下,我们只需要设置layout_content是否可见即可。
接下来我们就要考虑动画的实现了。
比较直接的做法,在title的点击监听里start一个Animator,看上去好像并没有什么不对,然而如果真的这样写了的话,我们会得到这样的结果:
|
|
动画虽然执行了,但是整个列表并没有重新布局!
这时候我们需要用另外一种方法来实现动画了,ValueAnimator。
使用ValueAnimator设置数值动画执行的起止数值,并在数变更监听中更新itemview的尺寸并通知父容器重新布局。
|
|
这样就能在动画执行期间实时的更新整个列表的布局了
接下来我们需要让itemview支持点击折叠操作,假设我们的所有item初始情况下都是折叠的状态,定义一个Map
修改itemview的onclick回调方法:
|
|
收缩动画就是上面那段,然后我们还需要实现一个展开的动画
|
|
在这短代码里我们首先指定layout_content不指定宽高的情况再次测量尺寸,并拿到测量后的高度,其实就是layout_content在wrap_content情况下的高度。创建一个从0到这个高度的动画,并在回调中更新布局。
这个时候item以及可用响应我们的点击事件,并执行相应的展开和折叠动画了,但是我们还有一个地方需要做处理,在RecyclerView中的ItemView会随着列表的滚动对其进行回收和复现,我们需要在ItemView被回收利用的时候对它的状态进行初始化,也就是在onBindViewHolder中设置layout_content的高度及Visible:
|
|
在注释代码的地方对layout_content的状态进行重置,这样就可用在滚动list的时候仍然保持正确的展开状态达到开篇的那种效果了。