在列表视图中仔细检查Android Studio

时间:2018-06-22 19:19:47

标签: android listview kotlin

我在开发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)
        }
    }
}

1 个答案:

答案 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}}方法中进行此操作。
  • 我还从未见过有人在listView上使用adapter。可能您是在尝试其他事情,而没有找到正确的wrap_content来做。
  • 您可以尝试更改View的宽度,然后查看代码没有问题。
  • 改为使用listView。它是对recyclerView的改进。