Lorsque je clique sur l'élément, j'obtiens
java.lang.ArrayIndexOutOfBoundsException: length = 10; index = -1
C'est ma méthode onCreateViewHolder , lorsque je clique sur l'élément, je veux ouvrir DetailActivity et envoyer des données avec intention
class ItemAlphabetAdapter(
private val alphabets: ArrayList<ItemAlphabet>
) : RecyclerView.Adapter<ItemAlphabetAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.alphabet_item, parent, false)
val holder = ViewHolder(view)
view.setOnClickListener {
val intent = Intent(parent.context, ItemAlphabetDetailActivity::class.java)
intent.putExtra("NAME", alphabets[holder.position].context)/*
intent.putExtra("CONTEXT", alphabets[holder.adapterPosition].context)
intent.putExtra("IMAGE", alphabets[holder.adapterPosition].image)
intent.putExtra("SOUND", alphabets[holder.adapterPosition].sound)*/
parent.context.startActivity(intent)
}
return ViewHolder(view)
}
override fun getItemCount(): Int = alphabets.size
override fun onBindViewHolder(holder: ItemAlphabetAdapter.ViewHolder, position: Int) {
val alphabet = alphabets[position]
holder.name.text = alphabet.name
holder.image.visibility = alphabet.image
}
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val image: ImageView = itemView.findViewById(R.id.alphabet_image)
val name: TextView = itemView.findViewById(R.id.alphabet_name)
}
}
Il est ma classe ItemAlphabetAdapter
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.alphabet_item, parent, false)
val holder = ViewHolder(view)
view.setOnClickListener {
val intent = Intent(parent.context, ItemAlphabetDetailActivity::class.java)
intent.putExtra("NAME", alphabets[holder.position].context)/*
intent.putExtra("CONTEXT", alphabets[holder.adapterPosition].context)
intent.putExtra("IMAGE", alphabets[holder.adapterPosition].image)
intent.putExtra("SOUND", alphabets[holder.adapterPosition].sound)*/
parent.context.startActivity(intent)
}
return ViewHolder(view)
}
3 Réponses :
Vous devrez écrire le code suivant
val intent = Intent(parent.context, ItemAlphabetDetailActivity::class.java)
intent.putExtra("NAME", alphabets[holder.position].context)/*
intent.putExtra("CONTEXT", alphabets[holder.adapterPosition].context)
intent.putExtra("IMAGE", alphabets[holder.adapterPosition].image)
intent.putExtra("SOUND", alphabets[holder.adapterPosition].sound)*/
parent.context.startActivity(intent)
dans onBindViewHolder () qui vous donne déjà la position comme l'un des paramètres
avez-vous lu onBindViewHolder docs: "Notez que contrairement à ListView, RecyclerView n'appellera plus cette méthode si la position de l'élément change dans l'ensemble de données sauf si l'élément lui-même est invalidé ou la nouvelle position ne peut pas être déterminé. Pour cette raison, vous ne devez utiliser le paramètre de position que lors de l'acquisition de l'élément de données associé dans cette méthode et ne devez pas en conserver une copie. Si vous avez besoin de la position d'un élément ultérieurement (par exemple dans un cliquez sur écouteur ), utilisez getAdapterPosition () qui aura la position de l'adaptateur mise à jour. "?
Problème avec mon onCreateViewHolder , je dois renvoyer holder , pas ViewHolder (view)
@Bekzhan avez-vous vu ce que j'ai écrit dans mon commentaire ci-dessus: "appelez itemView.setOnClickListener (this) dans votre ViewHolder personnalisé" ?
La méthode onCreateViewHolder n'est pas appelée à chaque fois que la vue de recyclage doit afficher une ligne, mais uniquement lorsqu'une nouvelle vue doit être créée et qu'il n'y a pas assez de vues à l'écran. Au lieu de cela, la méthode onBindViewHolder est appelée pour chaque position. Donc, pour avoir la position exacte de la ligne, utilisez holder.adapterPosition .
Essayez ceci. Déplacez votre setOnClickListener dans onBindViewHolder
itemView.setOnClickListener { if (position! = - 1) {
val intentIntent(itemView.context,ItemAlphabetDetailActivity::class.java)
intent.putExtra("NAME", alphabets[position].context)/*
intent.putExtra("CONTEXT", alphabets[position].context)
intent.putExtra("IMAGE", alphabets[position].image)
intent.putExtra("SOUND", alphabets[position].sound)*/
parent.context.startActivity(intent)
}}
vérifier la taille de votre arraylist
Les listes et les tableaux ne peuvent pas avoir une taille inférieure à 0, donc -1 un est hors limites et la JVM lève l'exception. Je suppose (sans la trace de pile) que le problème est dans la méthode
onBindViewHolder.appelez
itemView.setOnClickListener (this)dans votreViewHolderpersonnaliséessayez de déplacer votre setOnClickListener dans la méthode onBindViewHolder en utilisant la position: Int de cette méthode au lieu de holder.position