前言
最近有一些小伙伴问我,项目开发中ListView(RecyclerView)中嵌套RadioGroup(CheckBox)碰到状态消失,勾选错乱怎么办?这一句两句也说不清楚,索性写个文章出来。
注意
listview和recyclerview中嵌套RadioGroup(CheckBox)解决办法相同,以下以ListView为例。
勾选错乱
首先我们先贴出一部分代码,整体就是一个ListView,item里面就是一个checkbox,大家先看看效果。




大家可以很明显的看到,我先勾选了第一条,第二条,第三条,然后下面的条目居然被勾选了。
问题出在哪?
为了看问题在哪,我们在创建view的时候,打一个log,看看view究竟被创建了几次

log打印日志

创建了10次,那么当我往下滑的时候,也才增加了一次,也就是说,我们的条目总数只有11条,其他的条目都是复用这11条,所以导致错乱
解决办法
第一步:在实体类中增加一个字段
data class TestEntity(
var name: String,
//增加一个字段
var check: Boolean = false
)
第二步:在adapter中根据实体类的字段判断checkbox是否勾选
customViewHolder.checkBox.isChecked = testEntity.check
customViewHolder.checkBox.isChecked = testEntity.check
第三步:给checkbox设置监听,当状态改变时,改变对应实体类的值
customViewHolder.checkBox.setOnCheckedChangeListener { _, isChecked ->
testEntity.check = isChecked
}
完整Adapter代码

修改之后的效果图

我们发现,当我们手动设置状态之后,错乱的问题确实解决了,但是又碰到了一个新的问题,之前勾选的被自动取消了,那么我们继续解决勾选状态不见了的问题。

完美解决

RadioGroup解决
与checkbox同理,这里我只贴出来解决代码以供参考
class RadioGroupAdapter(private var context: Context, private var list: List<RadioGroupEntity>) : BaseAdapter() {
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
val customViewHolder: CustomViewHolder
var view: View? = convertView
if (view == null) {
customViewHolder = CustomViewHolder()
view = View.inflate(context, R.layout.item_listview, null)
customViewHolder.radioGroup = view.findViewById(R.id.radioGroup)
customViewHolder.tvTitle = view.findViewById(R.id.tvTitle)
view?.tag = customViewHolder
} else {
customViewHolder = view.tag as CustomViewHolder
view = convertView
}
//核心代码
customViewHolder.radioGroup.setOnCheckedChangeListener(null)
val testEntity = list[position]
customViewHolder.tvTitle.text = testEntity.title
//根据实体类来决定是否勾选以及勾选哪一个
when (testEntity.check) {
"A" -> customViewHolder.radioGroup.check(R.id.rbA)
"B" -> customViewHolder.radioGroup.check(R.id.rbB)
"C" -> customViewHolder.radioGroup.check(R.id.rbC)
else -> customViewHolder.radioGroup.clearCheck()
}
customViewHolder.radioGroup.setOnCheckedChangeListener { group, checkedId ->
when (checkedId) {
R.id.rbA -> testEntity.check = "A"
R.id.rbB -> testEntity.check = "B"
R.id.rbC -> testEntity.check = "C"
else -> testEntity.check = ""
}
}
return view!!
}
override fun getItem(position: Int): Any? {
return null
}
override fun getItemId(position: Int): Long {
return 0
}
override fun getCount(): Int {
return list.size
}
private class CustomViewHolder {
lateinit var radioGroup: RadioGroup
lateinit var tvTitle: TextView
}
}


网友评论