Android RecyclerView绘制页面的源码分析<一>
Android RecyclerView布局管理器LinearLayoutManager源码分析<二>
以上两篇讲述了RecycerView LinearLayoutManager 页面绘制以及子条目的布局,LinearLayoutManager 是一个线性的管理器即是控制垂直以及水平展示 一个条目表示一行,然而显示生活中有很多需求是一行展示多个子条目这个时候就用到了 GridLayoutManager 表格布局管理器 来实现这种需求
GridLayoutManager :继承于LinearLayoutManager的网格状布局管理器 默认一行展示一个
关键对象和方法
- 添加GridLayoutManager 负责布局RecyclerView的子布局
- onLayoutChildren() 布局子条目
- fill()填充子条目
- layoutChunk() 布局子条目(GridLayoutManager 实现了该方法所以会回调到GridLayoutManager 的layoutChunk())
- GridLayoutManager.layoutChunk() 布局表格
Demo:
package com.wu.material.activity.rv
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.wu.material.R
import com.wu.material.databinding.ActivityComplicatedRecyclerviewBinding
/**
* @author wkq
*
* @date 2022年03月01日 9:19
*
*@des
*
*/
class ComplicatedRecyclerViewActivity : AppCompatActivity() {
var binding: ActivityComplicatedRecyclerviewBinding? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView<ActivityComplicatedRecyclerviewBinding>(this, R.layout.activity_complicated_recyclerview)
initView()
}
private fun initView() {
var mAdapter = RecyclerViewActivity.DemoAdapter(this)
var gridLayoutManager= GridLayoutManager(this,4)
binding!!.rvContent.layoutManager = gridLayoutManager
//设置 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("Banner")
listData.add("Banner")
listData.add("Banner")
listData.add("Banner")
listData.add("Banner")
listData.add("Banner")
listData.add("Banner")
listData.add("Banner")
listData.add("Banner")
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()
// notifyItemChanged(2)
}
}
// 自定义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.设置GridLayoutManager
2.设置Adapter()(数据添加了观察者,数据增加就会调用 RecyceleView 添加子View)
3. Adapter的list添加数据 notifyDataSetChanged() 刷新适配器
4.观察者调用 GridLayoutManager .onLayoutChildren(),实质上是调用LinearLayoutManager的onLayoutChildren()布局添加数据
2.GridLayoutManager 处理子条目
2.1 GridLayoutManager 调用LinearLayoutManager的onLayoutChildren()
onLayoutChildren.pngonLayoutChildren.png
2.2 fill() 填充布局
onLayoutChildren.png fill.png2.2 layoutChunk() 因为GridLayoutManager 实现了layoutChunk 所以调用的是子类GridLayoutManager 的实现方法,
layoutChunk.png2.3 调用了RecyclerView的addView() --->addViewInt() ---> mChildHelper.addView(child, index, false);
image.png总结:
GridLayoutManager网格布局管理器 实现一行展示多个条目,本章解释了GridLayoutManager的简单源码实现表格布局的大概调用,下一章展示复杂的表格布局即展示不顾地条目数的表格布局
网友评论