在列表视图中双击Android studio

在列表视图中双击Android studio,android,listview,kotlin,Android,Listview,Kotlin,我在开发Android应用程序时遇到问题 该项目正在Android Studio中使用编程语言Kotlin进行开发 我试图实现列表的自定义适配器,但是当我运行程序时,会生成一个选择错误,该错误如下所示: 选择其中一个框时,id为n,如果n为奇数,则标记所有奇数框;如果n为偶数,则标记所有id相同的框 我附加了生成错误时在程序部分交互的模板、视图和类的代码 模板: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/

我在开发Android应用程序时遇到问题

该项目正在Android Studio中使用编程语言Kotlin进行开发

我试图实现列表的自定义适配器,但是当我运行程序时,会生成一个选择错误,该错误如下所示:

选择其中一个框时,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
}
}
类服务提供商活动:AppCompatActivity(){
重写创建时的乐趣(savedInstanceState:Bundle?){
super.onCreate(savedInstanceState)
setContentView(R.layout.activity\u servicio\u servicio)
val nombre=intent.getStringExtra(“nombre”)
val encargado=intent.getStringExtra(“encargado”)
val requisitos=intent.getStringArrayListExtra(“requisitos”)
val tViewNombre=findViewById(R.id.tServicio)
val tViewEncargado=findViewById(R.id.tEncargadoServicio)
val lViewRequisitos=findViewById(R.id.listViewRequisitos)
tViewNombre?.text=nombre
tViewEncargado?.text=encargado
val adaptador=AdaptadorCheck(此,请购单)
lViewRequisitos.adapter=适配器
}
}
适配器代码:

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)
        }
    }
}
classadaptedorcheck(var-context:context,items:ArrayList):BaseAdapter(){
私有变量项:ArrayList=ArrayList()
init{this.items=items}
覆盖视图(位置:Int,转换视图:View?,父视图:ViewGroup?):视图{
变量保持架:adadadorcheck.ViewHolder?=null
var vista:视图?=转换视图
如果(vista==null){
vista=LayoutFlater.from(上下文)。充气(R.layout.template\u检查,空)
holder=适配器检查。ViewHolder(vista)
vista.tag=holder
}否则{
holder=vista.tag as?适配器检查.ViewHolder
}
val item=getItem(位置)作为字符串
持有人?.nombre?.text=项目
返回vista!!
}
覆盖趣味getItem(位置:Int):任意{
返回项目?获取(位置)!!
}
覆盖getItemId(位置:Int):长{
返回位置。toLong()
}
重写fun getCount():Int{
返回项目?.count()!!
}
私有类视图持有者(视景:视图){
var nombre:复选框?=null
初始化{
nombre=vista.findviewbyd(R.id.cbCheck)
}
}
}

所以我尝试了完全相同的代码,发现了问题所在。要理解它,您必须首先了解
listView
的工作原理。从文件中-

ListView尝试重用视图对象以改进 性能,并避免响应用户滚动时出现延迟。

代码的问题在于
列表视图的
高度是
wrap\u content
,因此只有一个视图可见。因此,当您向下滚动时,listView会从顶部重用视图。因此,当您来到第三个视图时,
listView
重用视图位于位置1,并且由于您的
复选框被重用,它显示为好像第三个视图的
复选框已被选中

我没有什么建议

  • 当您要从列表中的用户获取输入时,必须将其存储在本地数组中的某个位置,以便再次检索这些值。否则,当用户滚动时,它们就会丢失
  • 您可以创建一个存储布尔值的数组,并根据布尔值更新
    复选框。当用户更改任何
    复选框的值时,也更新此数组。反之亦然。显示数组中
    复选框的最新状态,并在选中/取消选中
    复选框时更新数组。您将在
    adapter
    getView
    方法中执行此操作
  • 此外,我还从未见过有人在listView上使用
    wrap_content
    。可能您正在尝试其他操作,但没有找到正确的
    视图来执行此操作
  • 您可以尝试更改
    listView
    的宽度,看看代码是否有问题
  • 改为使用
    recyclerView
    。这是对
    列表视图的改进

也发布自定义适配器代码。完成了,我为这个错误感到抱歉@ranjan您还需要帮助吗?是的,我实现了其他解决方案,但我仍然需要帮助来解决这个问题