2017-10-04 1 views
3

J'ai beaucoup de recherche ce que j'ai fait est créé une liste d'éléments nombre simple et ayant la case à cocher Qui est cochée et non cochée, Alors quand je tape vite rapide sur la liste, il se bloque et générer ArrayIndexOutOfBound ExceptionAndroid: Recycler élément de vue rapide cliquetant il crash l'application

Je ne sais pas ce que je fais mal

ici est mon code

classe adaptateur

class SingleListItemHolder extends RecyclerView.ViewHolder implements View.OnClickListener { 

private TextView mItemDate, mFontSizeCategory; 
    private ImageView isChecked, isTrack, isUnChecked; 
    private int fontSize = 13; 
SingleListItemHolder(View v) { 
    super(v); 
    mFontSizeCategory = (TextView) v.findViewById(R.id.tv_font_size_category); 
    mItemDate = (TextView) v.findViewById(R.id.tv_recycler_view_list_header); 
    isChecked = (ImageView) v.findViewById(R.id.iv_recycler_view_list_item_selected); 
    isUnChecked = (ImageView) v.findViewById(R.id.iv_recycler_view_list_item_unselected); 
    isTrack = (ImageView) v.findViewById(R.id.iv_track); 
    v.setOnClickListener(this); 
    this.setIsRecyclable(false); 
} 

@Override 
public void onClick(View v) { 
    mSingleItemListModels.get(pos).setSelected(false); 
    notifyItemChanged(pos, mSingleItemListModels.get(pos)); 
    pos = getAdapterPosition(); 
    mSingleItemListModels.get(pos).setSelected(true); 
    notifyItemChanged(pos, mSingleItemListModels.get(pos)); 
} 
+0

Quelle est la ligne qui jette l'exception? –

+0

mSingleItemListModels.get (pos).setSelected (true); it throw error –

+0

Votre première ligne de onCLick devrait être pos = getAdapterPosition(); et puis vous pouvez accéder aux objets – Pabel

Répondre

2

Vous obtenez -1 Position dans getAdapterPosition() parce que quand u sont cliquez vite, il jette un certain temps la position -1

Vous pouvez le vérifier sur

if (pos != RecyclerView.NO_POSITION) { 
//Do your setting part 
} 

Modifier ce code

@Override 
public void onClick(View v) { 
    mSingleItemListModels.get(pos).setSelected(false); 
    notifyItemChanged(pos, mSingleItemListModels.get(pos)); 
    pos = getAdapterPosition(); 
    mSingleItemListModels.get(pos).setSelected(true); 
    notifyItemChanged(pos, mSingleItemListModels.get(pos)); 
} 

Code pour

@Override 
public void onClick(View v) { 
    mSingleItemListModels.get(pos).setSelected(false); 
    notifyItemChanged(pos, mSingleItemListModels.get(pos)); 
    pos = getAdapterPosition(); 
    if (pos != RecyclerView.NO_POSITION) { 
     mSingleItemListModels.get(pos).setSelected(true); 
     notifyItemChanged(pos, mSingleItemListModels.get(pos)); 
    } 
} 
3

Vous devez obtenir l'élément avant d'utiliser pos = getAdapterPosition();

@Override 
public void onClick(View v) { 

    pos = getAdapterPosition(); 


    mSingleItemListModels.get(pos).setSelected(false); 
    notifyItemChanged(pos, mSingleItemListModels.get(pos)); 
    mSingleItemListModels.get(pos).setSelected(true); 
    notifyItemChanged(pos, mSingleItemListModels.get(pos)); 
} 
4
pos = getAdapterPosition(); 

mouvement au-dessus

mSingleItemListModels.get(pos).setSelected(false); 
1

Vous abusez getAdapterPosition. Ce n'est pas une bonne idée de l'utiliser pour obtenir l'index de l'article affiché en cours. Encore plus mauvais qu'il peut également retourner -1 si vous avez appelé un changement d'adaptateur (que vous avez fait deux fois avec notifyItemChanged).

Voir la documentation pour elle here

Notez que si vous avez appelé notifyDataSetChanged(), jusqu'à ce que le passage suivant de la mise en page, la valeur de retour de cette méthode sera NO_POSITION.

La valeur de NO_POSITION est -1. Donc, au lieu d'implémenter le ClickListener à votre RecyclerView.ViewHolder, vous devez l'implémenter dans le onBindViewHolder parce que vous avez l'index actuel.

Utilisez ici

@Override 
    public void onBindViewHolder(ViewHolder holder, int position) { 
     // the position will be the correct one 
     // but don't store the position in a class field 
     // since it may change during scrolling 
    } 
+1

Vote Up parce que ce est la seule réponse qui résout le problème derrière le problème du PO. Le problème étant le PO a commencé avec une mauvaise conception de code. Les autres réponses (y compris la réponse acceptée) sont une solution rapide mais n'éliminent pas le vrai problème. – Barns