RecyclerView整合了ListView和GridView两者的特性,即可以用RecyclerView替换这两者。
itemCount、listitem只是为了预览而设置的,不是必须的。
网格列表
recyclerView.layoutManager = GridLayoutManager(this, 3)
线性列表
recyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)
瀑布列表
recyclerView.layoutManager = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)
recyclerView.adapter = RecycleAdapter()
abstract class RecycleAdapter(private var mDataSet: ArrayList, private var listener: IRecyclerViewListener?): RecyclerView.Adapter() {
// 按layoutResId保存holder
private var mHolders: SparseArray = SparseArray()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecycleViewHolder {
var mHolder = getHolder(viewType)
if (mHolder == null) {
// 创建holder
mHolder = RecycleViewHolder.get(parent, getLayoutId(viewType))
putHolder(viewType, mHolder)
}
return mHolder
}
override fun getItemCount(): Int {
return mDataSet.size
}
// 可以在此给列表项设置宽高
override fun onBindViewHolder(holder: RecycleViewHolder, position: Int) {
holder.itemView.setOnClickListener {
listener?.onItemClickListener(position)
}
holder.itemView.setOnLongClickListener {
listener?.onItemLongClickListener(position)
true
}
convert(holder, mDataSet[position], position)
}
private fun getHolder(viewType: Int): RecycleViewHolder? {
return mHolders.get(viewType)
}
private fun putHolder(viewType: Int, holder: RecycleViewHolder) {
mHolders.put(viewType, holder)
}
abstract fun getLayoutId(viewType: Int): Int
// 也可以在此给列表项设置宽高
abstract fun convert(holder: RecycleViewHolder, data: T, position: Int)
}
线性列表的间隔比较容易就不说了。
可添加多个间隔设置
recyclerView.addItemDecoration()
官方提供有DividerItemDecoration
recyclerView.addItemDecoration(DividerItemDecoration(context, orientation))
间隔实现类:可组合实现多种效果
class MyItemDecoration : RecyclerView.ItemDecoration() {
/**
* 设置padding:即设置Rect的left、top、right、bottom
*/
override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
super.getItemOffsets(outRect, view, parent, state)
}
/**
* 绘制背景
* canvas可以绘制各种图形文字
*/
override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
super.onDraw(c, parent, state)
}
/**
* 绘制遮罩
* canvas可以绘制各种图形文字
*/
override fun onDrawOver(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
super.onDrawOver(c, parent, state)
}
}
/**
* A {@link RecyclerView.LayoutManager} implementations that lays out items in a grid.
*
* By default, each item occupies 1 span. You can change it by providing a custom
* {@link SpanSizeLookup} instance via {@link #setSpanSizeLookup(SpanSizeLookup)}.
*/
public class GridLayoutManager extends LinearLayoutManager {}
通过官方代码注释可以看到,想要设置列表项占比,可以通过setSpanSizeLookup实现。以下是默认的SpanSizeLookup,可以看到列表项占比都是1,所以只需要覆写getSpanSize就行了
/**
* Default implementation for {@link SpanSizeLookup}. Each item occupies 1 span.
*/
public static final class DefaultSpanSizeLookup extends SpanSizeLookup {
@Override
public int getSpanSize(int position) {
return 1;
}
@Override
public int getSpanIndex(int position, int spanCount) {
return position % spanCount;
}
}
RecycleView目前支持三种LayoutManager,如果这三种LayoutManager不能满足UI设计效果,可以通过自定义LayoutManager进行修改。