基本使用
最基础的RecyclerView使用,共3步
- 在布局中声明RecycleView
- 配置RecyclerView,setLayoutManager(linearLayoutManage); 这个配置是必须的。
- 设置RecyclerView.Adapter,这里我们要注意Adapter的几个重要方法
//创建一个ViewHolder。主要是建立与View的绑定
public VH onCreateViewHolder(ViewGroup parent, int viewType);
//创建一个ViewHolder。主要是建立与View的绑定
public onBindViewHoler(VH holder, int position);
//显示View,itemView需要显示的内容
public int getItemCount();
//返回条目的个数
RecyclerView的属性
app:layoutManager="LinearLayoutManager" //指定layoutManager
android:descendantFocusability="blocksDescendants" //viewGroup会覆盖子类控件而直接获得焦点
RecyclerView.Adapter的其他回调方法
public void onViewDetachedFromWindow(VH holder);
//当适配器创建的view(即列表项view)被窗口分离(即滑动离开了当前窗口界面)就会被调用。
public void onViewAttachedToWindow(); //当列表项出现到可视界面的时候调用。
public int getItemViewType(int position);
//获取在该位置的类型,返回值会在 onCreateViewHolder中用到。利用该返回值,可以做一些其他事情,例如MulitiType使用来做ItemViewAdapter的索引。
进阶知识点
RecycleView的优化。
recycleView.setHasFixedSize(true);
//当每个条目的大小相等时,使用这个可以提高效率。
其他方法
recycleView.addItemDecoration(new DividerItemDecoration(this, VERTICAL));
//设置装饰器
recycleView.scrollToPosition(position);
//滚动到具体的位置
添加分割线
recyclerView.addItemDecoration(new MyRecycleViewItemDecoration());
//可以自定义分割线,系统提供了 DividerItemDecoration,可满足常用的需求
自定义分割线
主要实现两个方法,onDraw 实现分割线的绘制,getItemOffsets 实现itemView的偏移,不设置的话分割线会叠在itemView上。
public class MyRecycleViewItemDecoration extends RecyclerView.ItemDecoration {
private static int DIVIDE_HEIGHT = 20;
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDraw(c, parent, state);
//注意 parent.getChildCount()是返回一屏的子View数量
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
int top = child.getBottom();
int bottom = top + DIVIDE_HEIGHT;
ColorDrawable drawable = new ColorDrawable();
drawable.setColor(Color.parseColor("#33000000"));
drawable.setBounds(parent.getPaddingLeft(), top, parent.getWidth() - parent.getPaddingRight(), bottom);
drawable.draw(c);
}
}
/**
* 这里是设置itemView的偏移,用于分割线的绘制,否则会叠在itemView的上面
*/
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
outRect.set(0, 0, 0, DIVIDE_HEIGHT);
}
}
LayoutManager
使用GridLayoutManager.SpanSizeLookup可以对于Grid每行显示不同列数进行控制。
例如,第一行显示一列,其他显示两列的情况:
layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
return position == 0 ? 2 : 1;
}
});
MultiType
MultiType 是一个不错的对RecyclerView的封装。使用参考demo.
oneToMany 是一个类对应多个,ItemViewHolder
源码解读:MultiType实现了RecyclerView.Adapter, MultiTypeAdapter. 将其中方法置为final,通过代理模式映射到ItemViewBinder来具体实现。
它支持多种不同View混排,原理就是MultiTypeAdapter可以对应多个ItemViewBinder. 之间通过TypePool关联,包含了List<Class<?>> classes
; List<ItemViewBinder<?,?>>binders
; List<Linker<?>> linkers
;并对外提供了,register,unregister方法.将类与ItemViewBinder建立关联。
MultiTypeAdapter通过代理模式实现TypePool
,所以MultiTypeAdapter可以根据Class查找对应的ItemViewBinder
进而实现RecyclerView.Adapter. 另外,TypePool支持一个类对应多个ItemViewBinder
,通过Linker进行区分具体对应哪一个ItemViewBinder.
总结:对泛型的使用很值得学习。代码质量也很高,值得学习。