Android开发学习-RecyclerView中使用多种item

859 阅读1分钟

安卓学习过程中,系统为RecyclerView创建的Adapter只支持一种item。但是某些列表我需要多种,例如下面微信的设置页:

IMG_43649183F820-1.jpeg

除了隐私这种标题,里面的Item还有两种。

  1. “账号于安全”,不带下划线且下方有灰色隔离块。
  2. “青少年模式”,带有灰色下划线。

接下来就使用多种Item实现这种效果。

代码实现

创建List

image.png image.png

创建完成后会多出下面几个文件

image.png

image.png

创建Item(iOS中称为 Cell)

image.png

layout_test_item_one

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layout_test_item_one"
    android:layout_width="match_parent"
    android:layout_height="60dp"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical">
    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:background="@color/systemWhite"
        android:layout_height="60dp">

        <TextView
            android:id="@+id/me_cell_setting_title"
            android:layout_width="wrap_content"
            android:layout_height="20dp"
            android:text="账号于安全"
            android:lines="1"
            android:textColor="@color/titleColor"
            android:textSize="16sp"
            android:layout_marginStart="18dp"

            android:minWidth="60dp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <ImageView
            android:layout_width="16dp"
            android:layout_height="16dp"
            android:layout_marginEnd="6dp"

            android:background="@drawable/ic_right_arrow"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            />


        <TextView
            android:layout_width="match_parent"
            app:layout_constraintBottom_toBottomOf="parent"
            android:layout_marginStart="18dp"
            app:layout_constraintStart_toStartOf="parent"
            android:background="@color/dividerColor"
            app:layout_constraintEnd_toEndOf="parent"
            android:layout_height="1dp"/>

    </androidx.constraintlayout.widget.ConstraintLayout>

</LinearLayout>

ItemTwo

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layout_test_item_two"
    android:layout_width="match_parent"
    android:layout_height="69dp"
    android:background="@color/navigationBarBackgroundColor"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical">
    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:background="@color/systemWhite"
        android:layout_height="60dp">

        <TextView
            android:id="@+id/me_cell_setting_title"
            android:layout_width="wrap_content"
            android:layout_height="20dp"
            android:text="账号于安全"
            android:lines="1"
            android:textColor="@color/titleColor"
            android:textSize="16sp"
            android:layout_marginStart="18dp"

            android:minWidth="60dp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <ImageView
            android:layout_width="16dp"
            android:layout_height="16dp"
            android:layout_marginEnd="6dp"

            android:background="@drawable/ic_right_arrow"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            />


    </androidx.constraintlayout.widget.ConstraintLayout>

</LinearLayout>

把新建的两个Item引入到 TestItemRecyclerViewAdapter

1.首先
image.png
修改为
image.png

2.然后在 TestItemRecyclerViewAdapter 类里面 创建Item

inner class ViewHolderOne(itemView: View) : RecyclerView.ViewHolder(itemView) {
    var rv_1: LinearLayout = itemView.findViewById(R.id.layout_test_item_one)
    var titleText = rv_1.findViewById<TextView>(R.id.me_cell_setting_title)

}

inner class ViewHolderTwo(itemView: View) : RecyclerView.ViewHolder(itemView) {
    var rv_2: LinearLayout = itemView.findViewById(R.id.layout_test_item_two)
    var titleText = rv_2.findViewById<TextView>(R.id.me_cell_setting_title)
}

3.创建一个枚举管理Item

enum class ItemType(value:Int) {
    ONE(0),
    TWO(1)
}

4.通过枚举对item进行分类处理。

image.png

把values:List< PlaceholderItem>

image.png

然后 onCreateViewHolder onBindViewHolder 内部

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
    when(viewType){
        ItemType.ONE.ordinal -> {
            val view: View =
                LayoutInflater.from(parent.context)
                    .inflate(
                        R.layout.layout_test_item_one,
                        parent,
                        false
                    )
            return ViewHolderOne(view)
        }
        ItemType.TWO.ordinal -> {
            val view: View =
                LayoutInflater.from(parent.context)
                    .inflate(
                        R.layout.layout_test_item_two,
                        parent,
                        false
                    )
            return ViewHolderTwo(view)
        }
        else -> {
            val view: View =
                LayoutInflater.from(parent.context)
                    .inflate(
                        R.layout.layout_test_item_one,
                        parent,
                        false
                    )
            return ViewHolderOne(view)
        }
    }

}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
    val item = values[position]
    when(holder.itemViewType){
            ItemType.ONE.ordinal -> {
                var view : TestItemRecyclerViewAdapter.ViewHolderOne = holder as TestItemRecyclerViewAdapter.ViewHolderOne
                view.titleText.text = item
            }
            ItemType.TWO.ordinal -> {
                var view : TestItemRecyclerViewAdapter.ViewHolderTwo = holder as TestItemRecyclerViewAdapter.ViewHolderTwo
                view.titleText.text = item
            }
        }
}

到这里 TestItemRecyclerViewAdapter 文件就搞定了。

Fragment里

image.png

新建两个数组

val titleArray : List<String> = listOf(
    "账户于安全",
    "青少年模式", "关怀模式",
    "消息通知","设备", "通用",
    "朋友权限", "设备信息于权限","个人信息收集清单", "第三方信息共享清单",
    "帮助与反馈", "关于微信",
    "插件",
    "切换账号",
    "退出微信")

var viewTypes = arrayOf(
    ItemType.ONE,
    ItemType.ONE, ItemType.TWO,
    ItemType.ONE, ItemType.ONE, ItemType.TWO,
    ItemType.ONE, ItemType.ONE, ItemType.ONE, ItemType.TWO,
    ItemType.ONE, ItemType.TWO,
    ItemType.TWO,
    ItemType.TWO,
    ItemType.TWO
)
adapter = TestItemRecyclerViewAdapter(titleArray, viewTypes)

然后代码编译:

08FD0371FBBE83E0A0AEFD8898384549.jpg