
Android RecyclerView绘制页面的源码分析<一>
上篇文章,简单梳理了Recycle数据初始化和添加数据的源码调用.分析到LinearLayoutManager处理子条目的位置,今天就继续以LinearLayoutManager为例 查看源码看它怎样处理子布局的
关键对象和方法
- 添加
LayoutManager
负责布局RecyclerView的子布局 - onLayoutChildren() 布局子条目
- fill()填充子条目
- layoutChunk() 布局子条目
- ChildHelper 子条目的管理工具 ChildHelper .addView() 添加子条目
Demo:
class RecyclerViewActivity : AppCompatActivity() {
var binding: ActivityRecyclerviewBinding? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView<ActivityRecyclerviewBinding>(this, R.layout.activity_recyclerview)
initView()
}
private fun initView() {
var mAdapter = DemoAdapter(this)
//设置LayoutManager
binding!!.rvContent.layoutManager = LinearLayoutManager(this)
//设置 Adapter
binding!!.rvContent.adapter = mAdapter
var listData=ArrayList<String>()
listData.add("Android新控件")
listData.add("循环效果2:循环")
listData.add("Android")
listData.add("MotionLayout")
listData.add("Banner")
listData.add("循环效果2")
listData.add("Android新控件之MotionLayout实现Banner循环效果2:循环")
//刷新数据
mAdapter.addItems(listData)
}
// 自定义Adapter
class DemoAdapter(mContext: Context) : RecyclerView.Adapter<DemoViewHolder>() {
var mContext: Context? = null
var listData=ArrayList<String>()
init {
this.mContext = mContext
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DemoViewHolder {
var view = LayoutInflater.from(mContext).inflate(R.layout.item_demo, parent, false)
var viewHolder = DemoViewHolder(view)
return viewHolder
}
override fun onBindViewHolder(holder: DemoViewHolder, position: Int) {
var mHolder= holder
mHolder.getTextView().text=listData.get(position)
}
override fun getItemCount(): Int {
return listData.size
}
fun addItems(items:ArrayList<String>){
listData.addAll(items)
//刷新数据
notifyDataSetChanged()
}
}
// 自定义Holder
class DemoViewHolder(view: View) : RecyclerView.ViewHolder(view) {
var rootView:View?=null
init {
rootView = view
}
fun getTextView():TextView{
var tvContent= rootView!!.findViewById<TextView>(R.id.tv_content)
return tvContent
}
}
}
源码分析
1. RecyelerView 设置数据
1.设置LinearLayoutManager
2.设置Adapter()(数据添加了观察者,数据增加就会调用 RecyceleView 添加子View)
3. Adapter的list添加数据 notifyDataSetChanged() 刷新适配器
4.观察者调用 LinearLayoutManager.onLayoutChildren()布局添加数据
2.LinearLayoutManager 处理子条目
2.1 调用LinearLayoutManager.onLayoutChildren()


2.2 fill() 填充布局


2.2 layoutChunk() 布局子模块

2.3 调用了RecyclerView的addView() --->addViewInt() ---> mChildHelper.addView(child, index, false);

2.4 ChildHelper RecyclerView子条目的帮助类 调用 ChildHelper 的addView()

2.5 调用父布局ViewGroup的添加子View

总结:
LinearLayoutManager 管理RecyclerView 的子条目的填充布局以及调用RecyclerView添加子条目,也就意味着LayoutManager 处理RecyclerView的展示样式,各种样式以及位置处理都是在 LayoutManager 中实现的
网友评论