0

Fondamentalement, j'ai un recyclerview qui devrait remplir les données provenant du serveur, il y a 3 types d'éléments (photos, vidéos, essais) J'ai tout fait correctement et ça se voit normalement mais une fois que je commencer le défilement est écrasé avec cette erreur:Comment gérer getItemViewType avec 3 différents types de vues

java.lang.IndexOutOfBoundsException: Invalid index 2, size is 2 

les tableaux ne sont pas vides, la taille du tableau de photo = 2, vidéos = 1 et essai = 1. Je suis sûr que l'erreur est causée par getItemViewType méthode, Je ne peux vraiment pas comprendre l'idée, j'ai lu quelques définitions sur son rôle mais je peux encore gérer cette fois-ci!

Je veux juste que tous les articles de tous les tableaux soient dans un recycleur dans l'ordre!

Adaptateur:

public class GalleryAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { 

    final int VIEW_TYPE_PHOTO = 0; 
    final int VIEW_TYPE_VIDEO = 1; 
    final int VIEW_TYPE_ESSAY = 2; 

    public GalleryAdapter(ArrayList<Gallery.Photo> photo, ArrayList<Gallery.Vedio> video, 
     ArrayList<Gallery.Essay> essay, Context context) { 
    this.photo = photo; 
    this.video = video; 
    this.essay = essay; 
    this.context = context; 
    } 

    ArrayList<Gallery.Photo> photo; 
    ArrayList<Gallery.Vedio> video; 
    ArrayList<Gallery.Essay> essay; 
    Context context; 


    @Override 
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 

    // for photos and videos 
    View itemLayoutView1 = LayoutInflater.from(parent.getContext()).inflate(
     R.layout.gallery_item1, parent, false); 

    // for essay 
    View itemLayoutView2 = LayoutInflater.from(parent.getContext()).inflate(
     R.layout.gallery_item2, parent, false); 

    switch (viewType) { 

     case VIEW_TYPE_PHOTO: 

     PhotoViewHolder photoholder = new PhotoViewHolder(itemLayoutView1); 
     return photoholder; 

     case VIEW_TYPE_VIDEO: 

     VideoViewHolder videoholder = new VideoViewHolder(itemLayoutView1); 
     return videoholder; 

     case VIEW_TYPE_ESSAY: 

     EssayViewHolder essayholder = new EssayViewHolder(itemLayoutView2); 
     return essayholder; 

     default: 
     return null; 
    } 


    } 

    public int getViewTypeCount() { 
    return 3; 
    } 

    @Override 
    public int getItemViewType(int position) { 

    // return 0; // I tried this line only and still caused the same crash 

    // causes the same crash 
    switch (position) { 
     case 0: 
     return VIEW_TYPE_PHOTO; 
     case 1: 
     return VIEW_TYPE_VIDEO; 
     case 2: 
     return VIEW_TYPE_ESSAY; 
     default: 
     return -1; 
     } 
    } 


    @Override 
    public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) { 


    if (holder instanceof PhotoViewHolder) { 
     ((PhotoViewHolder) holder).pupulatePhoto(photo.get(position)); 
    } 

    if (holder instanceof VideoViewHolder) { 
     ((VideoViewHolder) holder).pupulateVideo(video.get(position)); 
    } 

    if (holder instanceof EssayViewHolder) { 
     ((EssayViewHolder) holder).pupulateEssay(essay.get(position)); 
    } 


    @Override 
    public int getItemCount() { 
    return photo.size() + video.size() + essay.size(); 
    } 

    public class PhotoViewHolder extends RecyclerView.ViewHolder { 

    private TextView title; 
    private TextView counter; 
    private TextView dummy; 
    private ImageView itemPic; 
    private ImageView eassyCover; 

    public PhotoViewHolder(View itemView) { 
     super(itemView); 

     title = (TextView) itemView.findViewById(R.id.title); 
     counter = (TextView) itemView.findViewById(R.id.counter); 
     dummy = (TextView) itemView.findViewById(R.id.dummy_txt); 
     itemPic = (ImageView) itemView.findViewById(R.id.item_pic); 
     eassyCover = (ImageView) itemView.findViewById(R.id.essay_cover); 
    } 


    public void pupulatePhoto(Gallery.Photo photo) { 
     title.setText("Photo " + photo.getTitle()); 
     Picasso.with(context).load(photo.getImage()).placeholder(R.drawable.bg_blur).into(itemPic); 
    } 
    } 

    public class VideoViewHolder extends RecyclerView.ViewHolder { 


    private TextView title; 
    private TextView counter; 
    private TextView dummy; 
    private ImageView itemPic; 
    private ImageView eassyCover; 

    public VideoViewHolder(View itemView) { 
     super(itemView); 

     title = (TextView) itemView.findViewById(R.id.title); 
     counter = (TextView) itemView.findViewById(R.id.counter); 
     dummy = (TextView) itemView.findViewById(R.id.dummy_txt); 
     itemPic = (ImageView) itemView.findViewById(R.id.item_pic); 
     eassyCover = (ImageView) itemView.findViewById(R.id.essay_cover); 
    } 

    public void pupulateVideo(Gallery.Vedio video) { 
     title.setText("Video " + video.getTitle()); 
     Picasso.with(context).load(video.getPreviewImage()).placeholder(R.drawable.bg_blur) 
      .into(itemPic); 
    } 

    } 

    public class EssayViewHolder extends RecyclerView.ViewHolder { 


    private TextView title; 
    private TextView counter; 
    private TextView dummy; 
    private ImageView itemPic; 
    private ImageView eassyCover; 

    public EssayViewHolder(View itemView) { 
     super(itemView); 

     title = (TextView) itemView.findViewById(R.id.title); 
     counter = (TextView) itemView.findViewById(R.id.counter); 
     dummy = (TextView) itemView.findViewById(R.id.dummy_txt); 
     itemPic = (ImageView) itemView.findViewById(R.id.item_pic); 
     eassyCover = (ImageView) itemView.findViewById(R.id.essay_cover); 
    } 

    public void pupulateEssay(Gallery.Essay essay) { 
     title.setText("Essay " + essay.getTitle()); 
    } 
    } 

} 

Mise à jour # 1

Le nouveau code pour l'adaptateur quand j'ai essayé combinant tous les trois ensemble:

public class GalleryAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { 

    final int VIEW_TYPE_PHOTO = 0; 
    final int VIEW_TYPE_VIDEO = 1; 
    final int VIEW_TYPE_ESSAY = 2; 

    ArrayList<Object> objects; 
    Context context; 

    public GalleryAdapter(ArrayList<Object> objects, Context context) { 
    this.objects = objects; 
    this.context = context; 
    } 

    @Override 
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    View view = LayoutInflater.from(parent.getContext()) 
     .inflate(R.layout.gallery_item2, parent, false); 

    switch (viewType) { 

     case VIEW_TYPE_PHOTO: 
     PhotoViewHolder photoholder = new PhotoViewHolder(view); 
     return photoholder; 

     case VIEW_TYPE_VIDEO: 
     VideoViewHolder videoholder = new VideoViewHolder(view); 
     return videoholder; 

     case VIEW_TYPE_ESSAY: 
     view = LayoutInflater.from(parent.getContext()).inflate(
      R.layout.gallery_item, parent, false); 

     EssayViewHolder essayholder = new EssayViewHolder(view); 
     return essayholder; 

     default: 
     return null; 
    } 

    } 

    @Override 
    public int getItemViewType(int position) { 

//Gallery.Photo and Gallery.Vedio are the models 
    if (objects.get(position) instanceof Gallery.Photo) { 
     return VIEW_TYPE_PHOTO; 
    } else if (objects.get(position) instanceof Gallery.Vedio) { 
     return VIEW_TYPE_VIDEO; 
    } else { 
     return VIEW_TYPE_ESSAY; 
    } 
    } 

    @Override 
    public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) { 

    if (getItemViewType(position) == VIEW_TYPE_PHOTO) { 


      // gives me NPE ! 
//  ((PhotoViewHolder) holder).pupulatePhoto(objects.get(position)); 


    } else if (getItemViewType(position) == VIEW_TYPE_VIDEO) { 


    } else { 


    } 


    @Override 
    public int getItemCount() { 
    return objects.size(); 
    } 

    public class PhotoViewHolder extends RecyclerView.ViewHolder { 


    private TextView title; 
    private TextView counter; 
    private TextView dummy; 
    private ImageView itemPic; 
    private ImageView eassyCover; 

    public PhotoViewHolder(View itemView) { 
     super(itemView); 

     title = (TextView) itemView.findViewById(R.id.title); 
     counter = (TextView) itemView.findViewById(R.id.counter); 
     dummy = (TextView) itemView.findViewById(R.id.dummy_txt); 
     itemPic = (ImageView) itemView.findViewById(R.id.item_pic); 
     eassyCover = (ImageView) itemView.findViewById(R.id.essay_cover); 
    } 

    public void pupulatePhoto(Gallery.Photo photo) { 
     title.setText("Photo " + photo.getTitle()); 
Picasso.with(context).load(photo.getImage()).placeholder(R.drawable.bg_blur).into(itemPic); 
    } 
    } 

    public class VideoViewHolder extends RecyclerView.ViewHolder { 


    private TextView title; 
    private TextView counter; 
    private TextView dummy; 
    private ImageView itemPic; 
    private ImageView eassyCover; 

    public VideoViewHolder(View itemView) { 
     super(itemView); 

     title = (TextView) itemView.findViewById(R.id.title); 
     counter = (TextView) itemView.findViewById(R.id.counter); 
     dummy = (TextView) itemView.findViewById(R.id.dummy_txt); 
     itemPic = (ImageView) itemView.findViewById(R.id.item_pic); 
     eassyCover = (ImageView) itemView.findViewById(R.id.essay_cover); 
    } 

    public void pupulateVideo(Gallery.Vedio video) { 

     title.setText("Video " + video.getTitle()); Picasso.with(context).load(video.getPreviewImage()).placeholder(R.drawable.bg_blur) 
      .into(itemPic); 
    } 

    } 

    public class EssayViewHolder extends RecyclerView.ViewHolder { 


    private TextView title; 
    private TextView counter; 
    private TextView dummy; 
    private ImageView itemPic; 
    private ImageView eassyCover; 

    public EssayViewHolder(View itemView) { 
     super(itemView); 

     title = (TextView) itemView.findViewById(R.id.title); 
     counter = (TextView) itemView.findViewById(R.id.counter); 
     dummy = (TextView) itemView.findViewById(R.id.dummy_txt); 
     itemPic = (ImageView) itemView.findViewById(R.id.item_pic); 
     eassyCover = (ImageView) itemView.findViewById(R.id.essay_cover); 
    } 

    public void pupulateEssay(Gallery.Essay essay) { 
     title.setText("Essay " + essay.getTitle()); 
    } 
    } 


} 

Il travaux super, mais je ne peux pas obtenir les positions des articles correctement? Quand j'appelle cette méthode pour peupler les données et les lier avec la vue ... il se bloque et me donne NPE?

((PhotoViewHolder) holder).pupulatePhoto(objects.get(position)); 

Mais cela me donne un NPE!? chaque fois que je utilise la position, il plante. Qu'est-ce que j'ai raté!?



Mise à jour # 2

Je l'ai résolu, j'ai oublié de jeter le modèle arraylist '_' donc je changé cette

((PhotoViewHolder) holder).pupulatePhoto(objects.get(position)); 

à cette

((PhotoViewHolder) holder).pupulatePhoto((Gallery.Photo) objects.get(position)); 

maintenant ça marche: D

Merci beaucoup les gars.!

+2

"Je veux juste que tous les articles de tous les tableaux soient dans un même recycleur!" - il n'y a pas d'ordre. Quelle est la commande? Au lieu d'avoir une seule collection de données de modèle, vous en avez trois ('photo',' video', 'essay'). Vous n'avez pas spécifié comment ces trois sont supposés être combinés pour créer un seul 'ReyclerView'. Cela n'a pas seulement un impact sur votre méthode 'getItemViewType()', mais aussi sur votre méthode 'onBindViewHolder()', car vous vous y écraserez également. – CommonsWare

+0

Peut-être qu'avec cette bibliothèque, il vous sera plus facile de réaliser ce que vous voulez: https: // github.com/afollestad/sectioned-recyclerview – algrid

+0

@CommonsWare ok je comprends ce que vous voulez dire, et si je combinais toutes les données des trois tableaux dans un tableau respectivement, de cette façon je peux obtenir le type et il serait dans l'ordre. droite? –

Répondre

0

La solution dans mon cas était de combiner toutes les trois liste de tableau en un de type Objet et instancie avec le constructeur de l'adaptateur, puis vérifier la position actuelle en utilisant instanceof avec le modèle correspondant.

@Override 
    public int getItemViewType(int position) { 

//Gallery.Photo and Gallery.Vedio are the models 
    if (objects.get(position) instanceof Gallery.Photo) { 
     return VIEW_TYPE_PHOTO; 
    } else if (objects.get(position) instanceof Gallery.Vedio) { 
     return VIEW_TYPE_VIDEO; 
    } else { 
     return VIEW_TYPE_ESSAY; 
    } 
    } 

Voir les mises à jour # 1 et # 2 pour plus de détails.