我在开发Android应用程序时遇到问题
该项目正在使用Studio Kotlin编程语言在Android Studio中开发
我试图对列表实现自定义适配器,但是当我运行程序时,会产生选择错误,该错误如下:
当选中其中一个ID为 n 的框时,如果 n 为奇数,则所有奇数框均被标记,当 n 是偶数,所有具有相同ID的框都被标记。
我将在发生错误时附加在程序部分交互的模板,视图和类的代码。
模板:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent">
<CheckBox
android:id="@+id/cbCheck"
android:layout_width="wrap_content"
android:layout_height="67dp"
android:layout_weight="1"
android:text="CheckBox"
android:textAlignment="textStart"
android:textAppearance="@style/TextAppearance.AppCompat.Display1"
android:textSize="24sp" />
</LinearLayout>
主要布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:orientation="vertical"
tools:context=".ServiciosServicioActivity">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="@+id/tViewServicio"
tools:layout_editor_absoluteX="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ListView
android:id="@+id/listViewRequisitos"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:layout_editor_absoluteX="22dp"
tools:layout_editor_absoluteY="300dp" />
</LinearLayout>
</ScrollView>
</LinearLayout>
类代码:
class ServiciosServicioActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_servicios_servicio)
val nombre = intent.getStringExtra("Nombre")
val encargado = intent.getStringExtra("Encargado")
val requisitos = intent.getStringArrayListExtra("Requisitos")
val tViewNombre = findViewById<TextView>(R.id.tServicio)
val tViewEncargado = findViewById<TextView>(R.id.tEncargadoServicio)
val lViewRequisitos = findViewById<ListView>(R.id.listViewRequisitos)
tViewNombre?.text = nombre
tViewEncargado?.text = encargado
val adaptador = AdaptadorCheck(this, requisitos)
lViewRequisitos.adapter = adaptador
}
}
适配器代码:
class AdaptadorCheck(var context: Context, items: ArrayList<String>):BaseAdapter() {
private var items:ArrayList<String> = ArrayList()
init{ this.items = items }
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
var holder: AdaptadorCheck.ViewHolder? = null
var vista:View? = convertView
if(vista == null ){
vista = LayoutInflater.from(context).inflate (R.layout.template_check, null)
holder = AdaptadorCheck.ViewHolder(vista)
vista.tag = holder
}else{
holder = vista.tag as? AdaptadorCheck.ViewHolder
}
val item = getItem(position) as String
holder?.nombre?.text = item
return vista!!
}
override fun getItem(position: Int): Any {
return items?.get(position)!!
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getCount(): Int {
return items?.count()!!
}
private class ViewHolder(vista: View){
var nombre: CheckBox? = null
init{
nombre = vista.findViewById(R.id.cbCheck)
}
}
}
答案 0 :(得分:2)
所以我尝试了完全相同的代码,然后发现了问题所在。要了解它,您必须首先了解listView
的工作方式。从文档中-
ListView尝试重用视图对象以进行改进 性能并避免用户滚动时出现滞后。 https://developer.android.com/reference/android/widget/ListView
您的代码存在问题,即您的listview's
高度为wrap_content
,因此只能看到1个视图。因此,当您向下滚动时,listView从顶部开始重用视图。因此,当您进入第三视图时,listView
在位置1处的重用视图由于您的checkbox
被重用了,因此它似乎好像已经检查了第三视图的checkbox
。
我建议的几件事。
checkbox
。当用户更改任何checkbox
的值时,也更新此数组。 反之亦然。显示checkbox
来自阵列的最新状态,并在选择/取消选择checkbox
时更新阵列。您将在getView
的{{1}}方法中进行此操作。 adapter
。可能您是在尝试其他事情,而没有找到正确的wrap_content
来做。View
的宽度,然后查看代码没有问题。listView
。它是对recyclerView
的改进。