如何解决ExpandableListAdapter 显示错误的 childViews
我正在编写一个应用程序来显示药物组、药物及其信息的树状视图。本质上,它是一个药物组的 ExpandableListView,它在孩子们查看时显示单个药物名称,并在点击时打开一个包含更多信息的新片段。
我一直坚持用正确的数据填充子视图。适配器似乎正确获取了组数据,并且从日志记录和调试来看,子数据似乎也被正确传递。但是, ExpandableListView 中 childViews 中的文本仅对我打开的第一组正确,下一组显示看似随机的内容(打开顺序无关紧要)。 childViews 的数量是正确的。详细视图 (onClick) 显示正确的信息,按下后退按钮后,菜单将显示正确的信息(但是,任何新打开的组仍然显示错误的内容)。
我至少做了 20 轮检查和澄清任何可疑代码,但无济于事。
用于说明的屏幕截图:
list view with two groups expanded
detail view,showing correct info (but not matching that shown in list view)
list view upon returning (notice contents now shown correctly)
class Medicationslistadapter(
private val context: Context,private val groupList: List<String>,private val itemList: List<List<String>>
) : Baseexpandablelistadapter() {
override fun getGroupCount(): Int {
return groupList.size
}
override fun getChildrenCount(groupPosition: Int): Int {
return itemList[groupPosition].size
}
override fun getGroup(groupPosition: Int): List<String> {
return itemList[groupPosition]
}
override fun getChild(groupPosition: Int,childPosition: Int): String {
return itemList[groupPosition][childPosition]
}
override fun getGroupId(groupPosition: Int): Long {
return groupPosition.toLong()
}
override fun getChildId(groupPosition: Int,childPosition: Int): Long {
return childPosition.toLong()
}
override fun hasstableIds(): Boolean {
return true
}
override fun getGroupView(
groupPosition: Int,isExpanded: Boolean,convertView: View?,parent: ViewGroup?,): View {
var groupView = convertView
if (groupView == null) {
val layoutInflater =
this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
groupView = layoutInflater.inflate(R.layout.medication_list_group,null)
val groupTextView: TextView = groupView.findViewById(R.id.text_group_name)
groupTextView.text = groupList[groupPosition]
} else return groupView
return groupView
}
override fun getChildView(
groupPosition: Int,childPosition: Int,isLastChild: Boolean,parent: ViewGroup?
): View {
var childView = convertView
if (childView == null) {
val layoutInflater =
this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
childView = layoutInflater.inflate(R.layout.medication_list_item,null)
childView.findViewById<TextView>(R.id.text_medication_name).text = getChild(groupPosition,childPosition)
} else return childView
return childView
}
override fun isChildSelectable(groupPosition: Int,childPosition: Int): Boolean {
return true
}
}
这是详细视图片段:
class MedicationItemFragment : Fragment() {
private lateinit var medicationName: String
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//get medication name from SafeArgs
arguments?.let {
medicationName = it.getString("medicationName").toString()
}
}
override fun onCreateView(
inflater: LayoutInflater,container: ViewGroup?,savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_medication_item,container,false)
}
override fun onViewCreated(view: View,savedInstanceState: Bundle?) {
super.onViewCreated(view,savedInstanceState)
// get the correct medication data
val medication: Medication = MedicationsListData().getMedication(medicationName)
// populate the view with current medication's data
view.findViewById<TextView>(R.id.text_pharmacodynamics_body).text =
medication.pharmacodynamics
view.findViewById<TextView>(R.id.text_contraindications_body).text =
medication.contraindications
}
companion object {
fun newInstance(): ParametersFragment = ParametersFragment()
}
}
这是提供适配器数据的类:
class GroupListData {
fun getItemData(): List<List<String>> {
return listof(
listof("amoxicillin + clavulanate","penicillin","clindamycin","vancomycin"),listof("epinephrine","norepinephrine","dopamine"),listof("metoprolol","adenosine","amiodarone"),listof("metoclopramide")
)
}
fun getGroupData(): List<String> {
return listof(
"antibiotics","vasopressors","antiarrhythmics","antiemetics"
)
}
}
如有必要,我可以详细说明或解释任何内容。非常感谢任何帮助!
解决方法
阅读后我现在明白问题是回收视图没有正确填充。对此的解决方法是停止回收视图并为每个孩子创建一个新视图:
override fun getChildView(
groupPosition: Int,childPosition: Int,isLastChild: Boolean,convertView: View?,parent: ViewGroup?
): View {
var childView = convertView
val layoutInflater = this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
childView = layoutInflater.inflate(R.layout.medication_list_item,null)
val medicationName = GroupListData().getItemData()[groupPosition][childPosition]
val medication: Medication = MedicationsListData().getMedication(medicationName)
childView.findViewById<TextView>(R.id.text_medication_name).text = medication.medicationName
if(medication.brandName != "null") {
childView.findViewById<TextView>(R.id.text_brand_name).text = medication.brandName
}
return childView
}
我不会完全认为这是一种解决方法,因为(非回收)视图的数量可能会导致一些性能问题。但是,如果其他任何人都在为同样的问题而苦苦挣扎(并且没有预料到性能问题),这很有效。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。