0

기본적으로 서버에서 오는 데이터를 채워야하는 recyclerview가 있습니다. 모든 유형의 항목 (사진, 비디오, 에세이)이 올바르게 있고 정상적으로 표시되지만 시작 스크롤이이 오류와 함께 추락 :3 가지보기 유형으로 getItemViewType을 처리하는 방법

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

배열이 비어 있지 않은, 내가 오류가 getItemViewType 방법에 의해 발생 확신 사진 = 2, 영상 = 1 및 에세이 = 1 의 배열 크기, 나는 정말로 그 배경에 대한 아이디어를 얻을 수 없다. 나는 그 역할에 대한 몇 가지 정의를 읽었지만 여전히이 시간을 다룰 수있다!

모든 배열의 모든 항목을 한 리사이클 러에서 순서대로 원합니다.

어댑터 :

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

} 

업데이트 # 1

어댑터에 대한 새로운 코드 나는 모든 세 개의 함께 결합 시도 :

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


} 

그것을 공장 좋아,하지만 항목의 위치를 ​​올바르게 가져올 수 없습니까? 이 메서드를 호출하여 데이터를 채우고 뷰를 바인딩하면 충돌이 발생하고 NPE가 표시됩니까?

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

하지만 나에게 NPE가 제공됩니다. 내가 그 위치를 사용할 때마다 그것은 부서진다. 내가 놓친 게 무엇입니까!?


업데이트 # 2


나는 그래서이

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

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

변경 '_'나는 모델의 ArrayList를 캐스팅하는 것을 잊었다, 그것을 해결

이제 작동합니다. D

감사합니다.

+2

"모든 배열의 모든 항목을 하나의 재활용 업체에서 순서대로 원합니다!" - 명령이 없습니다. 주문이란 무엇입니까? 모델 데이터를 하나만 수집하는 대신 세 가지 ('사진', '비디오', '에세이')가 있습니다. 이 세 가지가 결합되어 단일 'ReyclerView'를 만드는 방법을 지정하지 않았습니다. 그것은 당신의'getItemViewType()'메소드뿐만 아니라 당신의'onBindViewHolder()'메소드에도 충돌을 일으킬 것입니다. – CommonsWare

+0

어쩌면이 라이브러리를 사용하면 https : // github 원하는 것을 쉽게 얻을 수 있습니다.COM/afollestad/- recyclerview 구분 – algrid

+0

@CommonsWare 확인 난 당신이 무슨 뜻인지 얻을, 내가 무엇을 각각 하나 개의 배열에 세 개의 배열에서 모든 데이터를 결합하면, 나는 종류를 얻을 수 있으며 순서에있을 것입니다 이런 식으로.! 권리? –

답변

0

필자의 경우 솔루션은 3 개의 배열 목록을 모두 Object 형식에서 하나로 결합하여 어댑터 생성자로 인스턴스화 한 다음 instanceof을 해당 모델과 함께 사용하여 현재 위치를 확인합니다.

@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; 
    } 
    } 

자세한 내용은 업데이트 # 1 및 # 2를 참조하십시오.

관련 문제