美文网首页
安卓RecyclerViewAdapter的新玩法DataBin

安卓RecyclerViewAdapter的新玩法DataBin

作者: 长点点 | 来源:发表于2020-10-06 21:19 被阅读0次

    直奔主题
    首先来说一下,自定义RecyclerViewAdapter的基本步骤,不管是什么写法,这些都是定式:

    1.写一个类继承RecyclerView.Adapter

    class DemoRecyclerViewAdapter(
        var listDemoItem: ArrayList<listDemoItem>,
        val context: Context
    ) :
        RecyclerView.Adapter<ItemDemoRecyclerViewBinding.MyViewHolder>() {
    }
    

    写一个内部类,继承RecyclerView.ViewHolder

        class MyViewHolder(val binding: ItemDemoRecyclerViewBinding) :
            RecyclerView.ViewHolder(binding.root)
    

    2.复写(Override)一些必须复写的函数,这些函数都是抽象函数,所以如果子类不是抽象类,就必须要复写。

    不用担心,编译器都会有提示的


    提示有错误.png

    而且源码里很清楚,有三个抽象函数


    三个抽象函数.png
    在这里,我们直接用快捷键ctr+o,就会有弹出框,里面是所有能复写的父类或接口的方法:
    可以复写的.png

    直接用鼠标点击需要复写的方法就好了。

    3.向相应的方法里写入业务逻辑

    onCreateViewHolder:
    这个方法里创建视图:
    所以我们要返回一个viewHolder。
    这里我们直接用自定义的viewHolder类,新建一个实例,构造函数的参数,是我们ViewBinding。(ViewBinding可以dotcall的方式,访问XML文件中,带有id的控件。)

        override fun onCreateViewHolder(
            parent: ViewGroup,
            viewType: Int
        ): MyViewHolder {
    
            return MyViewHolder(
                ItemDemoRecyclerViewBinding.inflate(
                    LayoutInflater.from(parent.context),
                    parent,
                    false
                )
            )
        }
    

    onBindViewHolder
    生成好了视图以后,在这里写点击事件,绑定、更新视图属性。

     override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
            with(holder) {
                with(binding) {
                    (listDemoItem[position]).apply {
                        itemSettingsTextViewTitle.text = title
                        var onClockListener: View.OnClickListener = View.OnClickListener {
                        }
                        when (this) {
                            is Demo1 -> {
                                itemImageViewSettingsProfile.setImageResource(R.drawable.demo1)//图片自己找吧
                                onClockListener = View.OnClickListener {
                                  //添加点击事件的逻辑
                                }
                            }
                            is Demo2 -> {
                                itemImageViewSettingsProfile.setImageResource(R.drawable.demo2)
                                onClockListener = View.OnClickListener {
                                    //添加点击事件的逻辑
                                }
                            }
                            is Demo3 -> {
                                itemImageViewSettingsProfile.setImageResource(R.drawable.demo3)
                                onClockListener = View.OnClickListener {
                                    //添加点击事件的逻辑
                                }
                            }
                            is BaseDemoSettings -> {
                                itemImageViewSettingsProfile.setImageResource(R.drawable.demo)
                                onClockListener = View.OnClickListener {
                                    //添加点击事件的逻辑
                                }
                            }
                        }
                        root.setOnClickListener(onClockListener)
                    }
                }
            }
        }
    

    getItemCount
    Kotlin的简洁优雅,使得这个函数变成了一行代码

    override fun getItemCount() = listDemoItem.size
    

    总结一下,和传统的在viewHolder里写入大量的findViewById不同,直接使用ViewBinding使得代码非常简洁。

    其实listDemoItem参数,可以使用DataBinding的方式写。
    viewModel类

    class DemoModel : ViewModel() {
        private val _listDemoItem =
            MutableLiveData<ArrayList<DemoRecyclerViewAdapter.BaseDemoItem>>().apply {
                value = ArrayList()
            }
        val listDemoItem : LiveData<ArrayList<DemoRecyclerViewAdapter.BaseDemoItem>> =
            _listDemoItem 
    
        fun initlistDemoItem (context: Context) {
            with(ArrayList<DemoRecyclerViewAdapter.BaseDemoItem>()) {
                this.add(DemoRecyclerViewAdapter.Demo1(context))
                this.add(DemoRecyclerViewAdapter.Demo2(context))
                this.add(DemoRecyclerViewAdapter.Demo3(context))
                _listDemoItem .postValue(this)
            }
        }
    }
    

    使用

    //以下是在fragment里的写法,activity里把requireActivity()替换成this@MainActivity
    ViewModelProvider.AndroidViewModelFactory(requireActivity().application)
                .create(DemoModel ::class.java).apply {
                        with(
                            DemoRecyclerViewAdapter(
                                listDemoItem .value!!,
                                requireActivity()
                            )
                        ) {
                            recyclerViewDeomList.adapter = this
                            this@apply.listDemoItem .observe(
                                viewLifecycleOwner,
                                Observer {
                                    this.setData(it)
                                })
                        }
                        initlistDemoItem (requireActivity())
                }
    

    下面是所有类的源代码

    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recyclerViewDeomList"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
            app:layout_constraintBottom_toBottomOf="parent" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    DemoRecyclerViewAdapter.kt

    class DemoRecyclerViewAdapter(
        var listDemoItem: ArrayList<listDemoItem>,
        val context: Context
    ) :
        RecyclerView.Adapter<ItemDemoRecyclerViewBinding.MyViewHolder>() {
    
        class MyViewHolder(val binding: ItemDemoRecyclerViewBinding) :
            RecyclerView.ViewHolder(binding.root)
    
        override fun onCreateViewHolder(
            parent: ViewGroup,
            viewType: Int
        ): MyViewHolder {
    
            return MyViewHolder(
                ItemDemoRecyclerViewBinding.inflate(
                    LayoutInflater.from(parent.context),
                    parent,
                    false
                )
            )
        }
    
        override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
            with(holder) {
                with(binding) {
                    (listDemoItem[position]).apply {
                        itemSettingsTextViewTitle.text = title
                        var onClockListener: View.OnClickListener = View.OnClickListener {
                        }
                        when (this) {
                            is Demo1 -> {
                                itemImageViewSettingsProfile.setImageResource(R.drawable.demo1)//图片自己找吧
                                onClockListener = View.OnClickListener {
                                  //添加点击事件的逻辑
                                }
                            }
                            is Demo2 -> {
                                itemImageViewSettingsProfile.setImageResource(R.drawable.demo2)
                                onClockListener = View.OnClickListener {
                                    //添加点击事件的逻辑
                                }
                            }
                            is Demo3 -> {
                                itemImageViewSettingsProfile.setImageResource(R.drawable.demo3)
                                onClockListener = View.OnClickListener {
                                    //添加点击事件的逻辑
                                }
                            }
                            is BaseDemoSettings -> {
                                itemImageViewSettingsProfile.setImageResource(R.drawable.demo)
                                onClockListener = View.OnClickListener {
                                    //添加点击事件的逻辑
                                }
                            }
                        }
                        root.setOnClickListener(onClockListener)
                    }
                }
            }
        }
    
        override fun getItemCount() = listDemoItem.size
    
        fun setData(list: ArrayList<listDemoItem>) {
            listDemoItem= list
            notifyDataSetChanged()
        }
    
        abstract class listDemoItem(val title: String)
    
        class Demo1(context: Context) : listDemoItem(
            context.resources.getString(
                R.string.item_title_demo1
            )
        )
    
        class Demo2(context: Context) : listDemoItem(
            context.resources.getString(
                R.string.item_title_demo2
            )
        )
    
        class Demo3(context: Context) : listDemoItem(
            context.resources.getString(
                R.string.item_title_demo3
            )
        )
    }
    

    item_demo_recycler_view.xml

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="@dimen/spacing_small"
        android:paddingBottom="@dimen/spacing_small">
    
        <ImageView
            android:id="@+id/itemImageViewSettingsProfile"
            android:layout_width="20dp"
            android:layout_height="20dp"
            android:layout_marginStart="@dimen/spacing_normal"
            android:scaleType="fitCenter"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintDimensionRatio="1:1"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
        <TextView
            android:id="@+id/itemSettingsTextViewTitle"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="@string/pre_text_view_artist"
            android:layout_marginStart="@dimen/spacing_normal"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintLeft_toRightOf="@+id/itemImageViewSettingsProfile"
            app:layout_constraintTop_toTopOf="parent" />
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    最后在activity或者fragment等等地方使用

    with(ArrayList<DemoRecyclerViewAdapter.BaseDeviceDetailSettingsItem>()) {
                this.add(DemoRecyclerViewAdapter.Demo1(context))
                this.add(DemoRecyclerViewAdapter.Demo2(context))
                this.add(DemoRecyclerViewAdapter.Demo3(context))
                DemoRecyclerViewAdapter(
                                this,
                                requireActivity()//fragment里用这个
    //activity类里面,用 //this@MainActivity替换requireActivity()
                            )
            }
    
    

    在string.xml里添加


    添加在resources标签里
        <string name="item_title_demo1">demo1</string>
        <string name="item_title_demo2">demo2</string>
        <string name="item_title_demo3">demo3</string>
    

    相关文章

      网友评论

          本文标题:安卓RecyclerViewAdapter的新玩法DataBin

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