You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Kotlin实现支持有序多选、显示选择序号的RecyclerView?

用Kotlin实现有序多选的RecyclerView方案

核心思路

通过给列表项维护选中序号(未选中时为null),用一个有序列表记录选中项的顺序,点击时切换选中状态并自动调整后续项的序号,最终得到按选择顺序排列的数组。


1. 定义数据类

创建Place数据类,包含地点信息和选中序号字段:

data class Place(
    val id: Int,
    val name: String,
    var selectedOrder: Int? = null // 记录选中顺序,null表示未选中
)

2. 列表项布局(item_place.xml)

用圆形TextView显示选中序号,默认隐藏,选中后显示:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="16dp"
    android:orientation="horizontal"
    android:gravity="center_vertical">

    <!-- 选中序号显示 -->
    <TextView
        android:id="@+id/tv_order"
        android:layout_width="32dp"
        android:layout_height="32dp"
        android:background="@drawable/order_circle"
        android:gravity="center"
        android:textColor="@android:color/white"
        android:textSize="16sp"
        android:visibility="gone"/>

    <!-- 地点名称 -->
    <TextView
        android:id="@+id/tv_place_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:textSize="18sp"/>

</LinearLayout>

圆形背景(res/drawable/order_circle.xml)

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <solid android:color="@color/teal_200"/>
</shape>

3. 实现RecyclerView Adapter

处理点击事件、维护选中顺序、更新UI:

class PlaceAdapter(
    private val places: MutableList<Place>,
    private val onSelectedListUpdated: (List<Place>) -> Unit // 回调通知选中列表变化
) : RecyclerView.Adapter<PlaceAdapter.PlaceViewHolder>() {

    // 按选择顺序存储选中的地点
    private val selectedPlaces = mutableListOf<Place>()

    inner class PlaceViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val tvOrder: TextView = itemView.findViewById(R.id.tv_order)
        val tvPlaceName: TextView = itemView.findViewById(R.id.tv_place_name)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PlaceViewHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.item_place, parent, false)
        return PlaceViewHolder(view)
    }

    override fun onBindViewHolder(holder: PlaceViewHolder, position: Int) {
        val place = places[position]
        holder.tvPlaceName.text = place.name

        // 更新序号显示
        place.selectedOrder?.let {
            holder.tvOrder.visibility = View.VISIBLE
            holder.tvOrder.text = it.toString()
        } ?: run {
            holder.tvOrder.visibility = View.GONE
        }

        // 处理选中/取消选中逻辑
        holder.itemView.setOnClickListener {
            if (place.selectedOrder != null) {
                // 取消选中:移除并重新排序后续项的序号
                selectedPlaces.remove(place)
                place.selectedOrder = null
                selectedPlaces.forEachIndexed { index, selectedPlace ->
                    selectedPlace.selectedOrder = index + 1
                }
                notifyDataSetChanged()
            } else {
                // 添加选中:分配新序号并加入有序列表
                place.selectedOrder = selectedPlaces.size + 1
                selectedPlaces.add(place)
                notifyItemChanged(position)
            }
            // 把最新的有序选中列表传递给外部
            onSelectedListUpdated(selectedPlaces.toList())
        }
    }

    override fun getItemCount() = places.size
}

4. 在Activity中使用

初始化RecyclerView,获取最终的有序选中列表:

class MainActivity : AppCompatActivity() {

    private lateinit var recyclerView: RecyclerView
    private var orderedSelectedPlaces = listOf<Place>() // 存储最终选中的有序地点

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        recyclerView = findViewById(R.id.recyclerView)
        recyclerView.layoutManager = LinearLayoutManager(this)

        // 模拟测试数据
        val testPlaces = mutableListOf(
            Place(1, "天安门广场"),
            Place(2, "故宫博物院"),
            Place(3, "颐和园"),
            Place(4, "八达岭长城"),
            Place(5, "天坛公园")
        )

        val adapter = PlaceAdapter(testPlaces) { selectedList ->
            orderedSelectedPlaces = selectedList
            // 这里可以做后续导航逻辑,比如打印选中顺序
            Log.d("SelectedOrder", orderedSelectedPlaces.joinToString { "${it.name}(序号:${it.selectedOrder})" })
        }
        recyclerView.adapter = adapter
    }
}

内容的提问来源于stack exchange,提问作者Юля Муравьева

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 23:41:18