Android应用开发中Recyclerview的使用频率非常高,多布局是使用Recyclerview经常实现效果之一。这里简单介绍一下多布局的基本开发流程,实现一个简单的多布局效果。
实现如下效果图:
一、创建数据类
创建数据类,用以模拟多布局填充数据。文中数据类以布尔值作为标识判断是否是标题数据。
data class Types(
/**
* 是否标题
*/
val isTitle: Boolean? = false,
/**
* 标题
*/
val title: String? = null,
/**
* 图标
*/
val icon: Int? = 0,
/**
* 名称
*/
val name: String? = null
)
二、创建网格布局
使用Recyclerview创建常见的网格布局,最后再以此为基础实现多布局效果。
布局
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
适配器
class MultiLayoutsAdapter(val data: MutableList<Types> /*数据集合*/) :
RecyclerView.Adapter<RecyclerView.ViewHolder>(){
//视图持有,提供视图的引用。
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
//布局控件
}
//创建新视图
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
//引用item布局文件
}
//替换视图的内容
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
//从数据集合中获取元素替换视图内容
}
//返回数据集合的大小
override fun getItemCount(): Int {
//数据集合大小
}
}
Activity
//设置网格布局管理器
val manager = GridLayoutManager(this, 4)
recyclerView.layoutManager = manager
//设置用于描述item的适配器
val adapter = MultiLayoutsAdapter(loadData() /*数据集合*/)
recyclerView.adapter = adapter
三、创建多布局视图
分别创建“标题”,“内容”视图。
标题
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/bg_title_shape"
android:gravity="center"
android:textColor="@color/white"
android:textSize="13sp"
android:textStyle="bold" />
内容
<FrameLayout
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@drawable/bg_content_shape">
<ImageView
android:id="@+id/iv_content_icon"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center"
android:background="@drawable/bg_content_shape"
android:src="@drawable/ic_tee" />
</FrameLayout>
<TextView
android:id="@+id/tv_content_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:textColor="@color/black"
android:textSize="13sp"
android:textStyle="bold" />
四、修改适配器和Activity
在创建好的网格布局适配器和Activity的基础上进行修改,最终实现多布局的效果。
适配器
class MultiLayoutsAdapter(val data: MutableList<Types> /*数据集合*/) : RecyclerView.Adapter<RecyclerView.ViewHolder>(){
//第一步,删除ViewHolder,分别创建标题和内容的视图持有TitleViewHolder、ContentViewHolder。
// //视图持有,提供视图的引用
// class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
// //布局控件
// }
//视图持有,提供标题视图的引用。
class TitleViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val tvTitle: TextView
init {
tvTitle = view.findViewById(R.id.tv_title)
}
}
//视图持有,提供内容视图的引用。
class ContentViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val ivIcon: ImageView
val tvName: TextView
init {
ivIcon = view.findViewById(R.id.iv_content_icon)
tvName = view.findViewById(R.id.tv_content_name)
}
}
//创建新视图
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
//第三步,创建新视图,根据标题或内容创建布局。
return if (isTitle(viewType)) {
val view =
LayoutInflater.from(parent.context).inflate(R.layout.item_rlv_title, parent, false)
TitleViewHolder(view)
} else {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_rlv_content, parent, false)
ContentViewHolder(view)
}
}
//替换视图的内容
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
//第四步,判断持有类型,从数据集合中获取元素并用该元素替换视图的内容。
if (holder is TitleViewHolder) {
holder.tvTitle.text = data[position].title
} else if (holder is ContentViewHolder) {
holder.ivIcon.setImageResource(data[position].icon!!)
holder.tvName.text = data[position].name
}
}
//返回数据集合的大小
override fun getItemCount(): Int {
//第五步,返回数据集合大小。
return data.size
}
//第二步,提供视图类型判断。
//获取Item视图类型
override fun getItemViewType(position: Int): Int {
if (isTitle(position)) {
return position
}
return 1
}
//判断是否是标题
private fun isTitle(position: Int): Boolean {
return data[position].isTitle == true
}
}
Activity
//设置网格布局管理器
val manager = GridLayoutManager(this, 4)
recyclerView.layoutManager = manager
//关键代码
//设置标题占多少个spanCount
manager.spanSizeLookup = (object : GridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int): Int {
if (loadData()[position].isTitle == true) {
return manager.spanCount
}
return 1
}
})
//设置用于描述item的适配器
val adapter = MultiLayoutsAdapter(loadData() /*数据集合*/)
recyclerView.adapter = adapter
最后
到此我们实现了一个非常简单的多布局类型案例,希望对你有所帮助。