1
votes

Obtenir ArrayIndexOutOfBoundsException dans la classe Adapter

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)
}


4 commentaires

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 votre ViewHolder personnalisé


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


3 Réponses :


0
votes

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


3 commentaires

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é" ?



0
votes

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 .


0 commentaires

0
votes

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)
}}


0 commentaires