美文网首页
RecyclerView 多视图规范

RecyclerView 多视图规范

作者: 天敦敦 | 来源:发表于2020-11-06 04:00 被阅读0次

    一、需求及规范

    1、需求

    RecyclerView 是我们常用的列表控件,直接使用时通常大量代码编写于 Adapter 中,当 item 包含视图类型过多时,Adapter 会臃肿不堪,故需要将各个类型视图单独定义编写。

    2、规范

    主要定义五个模块:adapter、viewHolder、viewHolderFactory、itemView、model

    adapter:及 RecyclerView.Adapter 适配器,用来整合填充数据
    viewHolder:及 RecyclerView.ViewHolder 视图固定器,用来实现视图重用
    viewHolderFactory:创建 viewHolder,并实现多类型视图设置
    itemView:item视图代码编写
    model:定义公共model,便于使用

    二、代码编写

    RecyclerViewAdapter

    abstract class RecyclerViewAdapter<M: RecyclerViewModel>(private var context: Context) :
        RecyclerView.Adapter<RecyclerViewHolder<M, out ViewDataBinding, out ItemRecyclerView<M, out ViewDataBinding>>>() {
    
        private val dataList: MutableList<M> by lazy {
            ArrayList<M>()
        }
    
        fun addAllDataList(dataList: List<M>) {
            this.dataList.addAll(dataList)
            notifyDataSetChanged()
        }
    
        override fun getItemCount(): Int {
            return dataList.size
        }
    
        override fun onCreateViewHolder(
            parent: ViewGroup,
            viewType: Int
        ): RecyclerViewHolder<M, out ViewDataBinding, out ItemRecyclerView<M, out ViewDataBinding>> {
            return createViewHolderFactory().createViewHolder(context, parent, viewType)
        }
    
        protected abstract fun createViewHolderFactory(): ViewHolderFactory<M>
    
    
        override fun onBindViewHolder(
            holder: RecyclerViewHolder<M, out ViewDataBinding, out ItemRecyclerView<M, out ViewDataBinding>>,
            position: Int
        ) {
            holder.itemRecyclerView.dataBinding(dataList[position], position)
        }
    
    }    
    

    RecyclerViewHolder

    class RecyclerViewHolder<M: RecyclerViewModel, VDB: ViewDataBinding, V: ItemRecyclerView<M, VDB>>(var itemRecyclerView: V)
        : RecyclerView.ViewHolder(itemRecyclerView.rootView)
    

    ViewHolderFactory

    abstract class ViewHolderFactory<M: RecyclerViewModel> {
        abstract fun createViewHolder(context: Context, parent: ViewGroup, viewType: Int):
                RecyclerViewHolder<M, out ViewDataBinding, out ItemRecyclerView<M, out ViewDataBinding>>
    }
    

    ItemRecyclerView

    abstract class ItemRecyclerView<M: RecyclerViewModel, VDB: ViewDataBinding>(context: Context, parent: ViewGroup) {
    
        val binding: VDB by lazy {
            DataBindingUtil.inflate(LayoutInflater.from(context), getItemLayoutId(), parent, false) as VDB
        }
    
        val viewHolder: RecyclerViewHolder<M, VDB, out ItemRecyclerView<M, VDB>> by lazy {
            RecyclerViewHolder(this)
        }
    
        val rootView: View by lazy {
            binding.root
        }
    
        abstract fun dataBinding(m: M, position: Int)
    
        abstract fun getItemLayoutId(): Int
    }
    

    RecyclerViewModel

    abstract class RecyclerViewModel
    

    三、使用

    DemoViewHolderFactory

    class DemoViewHolderFactory: ViewHolderFactory<DemoModel>() {
        override fun createViewHolder(
            context: Context,
            parent: ViewGroup,
            viewType: Int
        ): RecyclerViewHolder<DemoModel, *, *> {
            return DemoItemView(context, parent).viewHolder
        }
    }
    

    DemoItemView

    class DemoItemView(context: Context, parent: ViewGroup):     ItemRecyclerView<DemoModel, ItemDemoBinding>(context, parent) {
        override fun dataBinding(m: DemoModel, position: Int) {
            binding.demo = m
        }
    
        override fun getItemLayoutId(): Int {
            return R.layout.item_demo
        }
    }
    

    DemoModel

    class DemoModel: RecyclerViewModel() {
        var title: String? = null
        var content: String? = null
    }
    

    DemoAdapter

    class DemoAdapter(context: Context): RecyclerViewAdapter<DemoModel>(context) {
        override fun createViewHolderFactory(): ViewHolderFactory<DemoModel> {
            return DemoViewHolderFactory()
        }
    }
    

    MainActivity

    class MainActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            val binding: ActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
            binding.demoListView.layoutManager = LinearLayoutManager(this)
            val adapter = DemoAdapter(this)
            binding.demoListView.adapter = adapter
    
            val dataList = ArrayList<DemoModel>()
            for (i in 0..20) {
                val data = DemoModel()
                data.title = "title $i"
                data.content = "content $i"
                dataList.add(data)
            }
    
            adapter.addAllDataList(dataList)
        }
    }
    

    activity_main

    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    
        <data>
    
        </data>
    
        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context=".MainActivity">
    
            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/demo_list_View"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
    
        </androidx.constraintlayout.widget.ConstraintLayout>
    </layout>
    

    item_demo

    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    
        <data>
            <variable
                name="demo"
                type="com.ww7h.bigobj.DemoModel" />
        </data>
    
        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
    
            <TextView
                android:id="@+id/title"
                android:text="@{demo.title}"
                app:layout_constraintTop_toTopOf="parent"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>
    
            <TextView
                android:text="@{demo.content}"
                app:layout_constraintTop_toBottomOf="@+id/title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>
    
        </androidx.constraintlayout.widget.ConstraintLayout>
    </layout>

    相关文章

      网友评论

          本文标题:RecyclerView 多视图规范

          本文链接:https://www.haomeiwen.com/subject/xguzvktx.html