这几天有时间,做了一个类似淘宝推荐好店的效果,而其中的ui以及层叠包括动画都没有时间做,而且好像做出来也没多好看orz,先上图:,是中间向下滑动的部分 -_-||
该效果是类似于stackview的层叠滑动效果(后来才知道5.0有stackview这样的东西,但看了下源码估计实现思路差不多)。实际上要实现这样的效果还有一个思路,那就是自定义layoutmanager,且认为这种思路更好,最主要的原因是其拥有item的重用机制,以后有时间会考虑这样去实现,但本篇采用老方法,自定义,这样才能让人深入研究recyclerview内部的机制,重在学习。
实现思路
首先明确目标,和recyclerview一样,那就是数据从网络来,该控件可以按顺序加载显示这些数据,且可以翻页。看上去并不复杂,每一个步骤我们都很熟悉,但事情往往是我们越熟悉的东西越能让人可畏,一步一步来,我们将步骤分为数据层的处理,展示层的处理,以及数据和展示之间的绑定三个部分。
1 首先要说的是view,可以想象如果不使用view的重用,那么有多少个item就会有多少个view;那么如果要重用view,基础view该有多少个呢,答案是屏幕上可见多少个就得至少初始化多少个view,否则同时显示3个view而实际上基础view只有两个该怎么显示呢,所以我们有:
private int visibleViewCount = DEFAULT_COUNT;
但请注意这里是至少,Lucas Rocha有一篇文章还介绍过预加载和缓存延时,都是很麻烦的东西,这里就不考虑了。而本篇需求可看最多时,屏幕上会同时展示两个view(因为没有层叠,后面是可以做扩展的)。
2 然后是list数据,这里就不得不提到本篇的第一个坑:addview及其重载方法。这个坑使得上面的图片出现了四条数据与展示的映射线,原因是addview动态添加的视图展示机制是:先添加的在下面,后添加的覆盖先添加的在上面。而我们的数据list是不能更改数据顺序的,改了显示顺序就不对了,所以在循环添加视图的时候起初使用的是第3、4条线的做法,处理起来异常麻烦,特别是当移除一个item时需要往底下再添加一个view,就需要重新给所有view进行排序,这其中就免不了要不断的addview、removeview,那么重绘闪屏就无可避免,直到使用bringtofront,才回到第1、2条线的做法上来。
那么数据和view就可以不交叉的对应了。
3 数据绑定。
1)在控件初始化的时候,每一个item长什么样子是由外部决定的,也就是说这个item的rootview需要外部传入,而根据上面第一点可知,我们至少要初始化visibleViewCount个view,而本篇第二个坑(姑且算是遇到的阻碍)就是view只有在inflate()后才会产生一个新的view,换句话说外部需要调用inflate方法visibleViewCount次再传入我们的控件,这不科学。这时,我们便深刻了解到recyclerview的adapter的用处,为什么在使用listview或recyclerview类似的控件时都需要传入一个adapter就是这个原因。
public static abstract class CasAdapter<VH extends ViewHolder> {
public abstract VH onCreateView();
public abstract void onBindViewHolder(VH holder, int position);
public final VH createView() {
return onCreateView();
}
public final void bindViewHolder(VH holder, int position) {
onBindViewHolder(holder, position);
}
}
在初始化基础view的时候,我们只需要传入CasAdapter类型的实例,然后在初始化时调用onCreateView就能获得该