Recyclerview 中的单选按钮在 Kotlin 中无法正常工作

问题描述 投票:0回答:2
Adapter Class
--------------

class FilterByDataAdapter(
    val filterByData: (ArrayList<String>) -> Unit, val filterByDataRadioBtn: (String) -> Unit
) : RecyclerView.Adapter<FilterByDataAdapter.FilterByDataViewHolder>() {

    private lateinit var itemFilterByListBinding: ItemFilterByListBinding
    private lateinit var filerByDataList: ArrayList<FilterByItemDataModel>
    private lateinit var filterByName: String

    var filteredData: ArrayList<String> = arrayListOf()

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FilterByDataViewHolder {
        itemFilterByListBinding =
            ItemFilterByListBinding.inflate(LayoutInflater.from(parent.context), parent, false)

        return FilterByDataViewHolder(itemFilterByListBinding)
    }

    override fun onBindViewHolder(holder: FilterByDataViewHolder, position: Int) {
        val filterByDataItem = filerByDataList[position]
        filterByDataItem.let {
            holder.apply {
                this.bindFilterByData(it, filterByName)
            }
        }
    }

    override fun getItemCount(): Int {
        return filerByDataList.size
    }

    fun setFilterByDataList(
        filterByTimeList: ArrayList<FilterByItemDataModel>, filterName: String
    ) {
        filerByDataList = filterByTimeList
        filterByName = filterName
    }

    inner class FilterByDataViewHolder(itemFilterByListBinding: ItemFilterByListBinding) :
        RecyclerView.ViewHolder(itemFilterByListBinding.root) {
        fun bindFilterByData(filterByItemDataModel: FilterByItemDataModel, filterByName: String) {
            itemFilterByListBinding.filterItemTxt.text = filterByItemDataModel.itemName

            validateButtonChecked(filterByName, filterByItemDataModel)
        }

        private fun validateButtonChecked(
            filterByName: String, filterByItemDataModel: FilterByItemDataModel
        ) {
            when (filterByName) {
                TIME -> {
                    itemFilterByListBinding.filterRadioGroup.visibility = View.VISIBLE
                    itemFilterByListBinding.filterRadioBtn.isChecked = filterByItemDataModel.isChecked

                    itemFilterByListBinding.filterRadioBtn.setOnCheckedChangeListener { buttonView, isChecked ->

                    }
                }

                STATUS, VALIDITY -> {
                    itemFilterByListBinding.filterCheckBoxBtn.visibility = View.VISIBLE

                    itemFilterByListBinding.filterCheckBoxBtn.setOnCheckedChangeListener { buttonView, isChecked ->
                        filteredData = Utils.processCheckBoxItems(
                            filterByName, isChecked, filterByItemDataModel.itemName.toString()
                        )
                        filterByData.invoke(filteredData)
                    }
                }
            }
        }
    }
}


Fragment Class
---------------

class FilterByBottomSheetDialog(private val onShowResultClick: (ArrayList<String>) -> Unit) :
    BottomSheetDialogFragment() {

    private lateinit var dialogFilterLayoutBinding: DialogFilterLayoutBinding

    private lateinit var filterByData: ArrayList<FilterByItemDataModel>
    private lateinit var filterName: String

    private val filterByItemAdapter by lazy {
        FilterByDataAdapter(
            { action -> actionOnFilterByClick(action) },
            { item -> actionOnFilterByRadioBtnClick(item) })
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
    ): View? {
        dialogFilterLayoutBinding = DataBindingUtil.inflate(
            LayoutInflater.from(context), R.layout.dialog_filter_layout, null, false
        )
       return dialogFilterLayoutBinding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        if (::filterByData.isInitialized) {
            setFilterByDataRecyclerView(filterByData, filterName)
        }
    }

    private fun setFilterByDataRecyclerView(
        filterByTimeList: ArrayList<FilterByItemDataModel>, filterName: String
    ) {
        filterByItemAdapter.setFilterByDataList(getFilterByTimeList(), filterName)
        dialogFilterLayoutBinding.filterItemRecyclerView.adapter = filterByItemAdapter
    }

    fun getFilterByTimeList(): ArrayList<FilterByItemDataModel> {
        val timeArrayList = ArrayList<FilterByItemDataModel>()
        val data = arrayListOf("week", "month", "year")

        for (i in data.indices) {
            timeArrayList.add(
                FilterByItemDataModel(
                    itemName = data[i],
                    isChecked = false
                )
            )
        }

        return timeArrayList
    }

}

list item xml
---------------

<?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="filterItemName"
            type="com.xxx.xxxxx.datamodel.FilterByItemDataModel" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="5dp"
        android:layout_marginEnd="5dp">


        <androidx.appcompat.widget.AppCompatTextView
            android:id="@+id/filter_item_txt"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="5dp"
            android:layout_marginBottom="5dp"
            android:padding="10dp"
            android:textColor="@color/txt_black"
            android:textSize="14sp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:layout_marginTop="5dp"
            android:background="@color/txt_light_grey"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/filter_item_txt" />

        <RadioGroup
            android:id="@+id/filter_radio_group"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:visibility="gone"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent">

            <androidx.appcompat.widget.AppCompatRadioButton
                android:id="@+id/filter_radio_btn"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="5dp"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintTop_toTopOf="parent" />
        </RadioGroup>

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>


大家好, 我在回收器视图中检查和取消检查单选按钮时遇到问题。我正在显示数组列表中的数据并将其显示在回收器视图中。但是当我尝试选择时,会选择所有选定的项目,而不是取消选择最后选中的项目。

任何帮助将不胜感激。提前感谢大家。 这是我的代码供参考,

android kotlin android-studio android-recyclerview radio-button
2个回答
0
投票

更新列表的整个逻辑将在视图模型中完成,并且通过在适配器中使用不同的内容,这些更改将毫无困难地发生,所以

您触发一个项目的选择 - >更新视图模型中的列表,然后您提交修改后的列表并观察它,然后列表得到更新,尝试一下,如果您需要任何帮助,只需发布您的进度并乐意提供帮助


0
投票

该问题可能与您处理

FilterByDataAdapter
中单选按钮的选中状态的方式有关。

您可以维护一个变量来跟踪当前选定的位置,并在选择新项目时更新它。以下是修改您的

FilterByDataAdapter
:

的方法
class FilterByDataAdapter(
    val filterByData: (ArrayList<String>) -> Unit, 
    val filterByDataRadioBtn: (String) -> Unit
) : RecyclerView.Adapter<FilterByDataAdapter.FilterByDataViewHolder>() {

    // ... (other existing code)

    private var selectedPosition: Int = RecyclerView.NO_POSITION

    override fun onBindViewHolder(holder: FilterByDataViewHolder, position: Int) {
        val filterByDataItem = filerByDataList[position]
        filterByDataItem.let {
            holder.apply {
                this.bindFilterByData(it, filterByName, position)
            }
        }
    }

    inner class FilterByDataViewHolder(itemFilterByListBinding: ItemFilterByListBinding) :
        RecyclerView.ViewHolder(itemFilterByListBinding.root) {

        fun bindFilterByData(
            filterByItemDataModel: FilterByItemDataModel,
            filterByName: String,
            position: Int
        ) {
            // ... (other existing code)

            when (filterByName) {
                TIME -> {
                    // ... (other existing code)

                    itemFilterByListBinding.filterRadioBtn.isChecked =
                        position == selectedPosition

                    itemFilterByListBinding.filterRadioBtn.setOnClickListener {
                        if (position != selectedPosition) {
                            // Clear the previous selection
                            notifyItemChanged(selectedPosition)
                            // Update the selected position
                            selectedPosition = position
                            // Update the UI for the newly selected item
                            notifyItemChanged(position)
                        }
                    }
                }
                
                // ... (other existing code)
            }
        }
    }
}

此修改可确保在

RadioGroup
内一次仅选择一个单选按钮。
selectedPosition
变量用于跟踪当前选定的位置,
notifyItemChanged
方法用于相应地更新 UI。

© www.soinside.com 2019 - 2024. All rights reserved.