Reputation: 53
I have a problem developing Android application
The project is being developed in Android Studio, with the programming language Kotlin
I was trying to implement a custom adapter to a list, however when I run the program a selection error is generated, this error is as follows:
When one of the boxes is selected, with an id n, if n is odd, all the odd boxes are marked, and it happens the same when n is even, all the boxes with the same id are marked.
I attach the code of the template, the view and the class that interact in the part of the program when the error is generated.
Template:
<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>
Main Layout:
<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 code:
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
}
}
Adapter Code:
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)
}
}
}
Upvotes: 3
Views: 215
Reputation: 1146
So I tried exact same code and I found out the problem. To understand it, you'll have to first understand how listView
works. From the documentation -
ListView attempts to reuse view objects in order to improve performance and avoid a lag in response to user scrolls. https://developer.android.com/reference/android/widget/ListView
Problem with your code is that your listview's
height is wrap_content
and because of that only 1 view is visible. So when you scroll down, listView reuse view from the top. So when you come to 3rd view, listView
reuse view at position 1 and since your checkbox
is reused, it shows as if 3rd view's checkbox
was already checked.
Few things I would suggest.
checkbox
. Also update this array when user changes value of any checkbox
. It should work vice versa. Showing latest state of checkbox
from the array and updating the array when checkbox
is selected/unselected. This you'll do in getView
method of adapter
.wrap_content
over a listView. Probably you are trying to something else and not finding the right View
to do it.listView
and see that there is nothing wrong with your code.recyclerView
instead. It is an improvement to listView
.Upvotes: 2