viewHolder.getAdapterPosition () в адаптере возвращает -1 позицию, и это вызвало IndexOutOfBoundException

1

я пытаюсь реализовать лучшие практики для обработки onclick в адаптере, но у меня возникла проблема IndexOutOfBoundException когда getAdapterPostition внутри onCreateViewHolder, что не так с моим кодом?

Я уже пытаюсь проверить, но пока не решаю.

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

private DataFrontVideo datas;
private Context context;

public VideoAdapter(DataFrontVideo datas, Context context) {
    this.datas = datas;
    this.context = context;
}

@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
    View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_video,null);
    final ViewHolder viewHolder = new ViewHolder(view);
    view.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            DataVideo video = datas.getContent().get(viewHolder.getAdapterPosition()); // ERROR HERE
            Intent intent = new Intent(context,DetailActivity.class);
            intent.putExtra("datas",video);
            context.startActivity(intent);
        }
    });
    return new ViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
    DataVideo dataVideo = datas.getContent().get(position);
    ViewHolder vh = (ViewHolder)viewHolder;
    vh.tvTitle.setText(dataVideo.getJudul());
    vh.tvArtis.setText(dataVideo.getAlias());
    vh.tvPrice.setText((dataVideo.getPrice().equals("0")?"Gratis":dataVideo.getPrice()));
    Glide.with(vh.img.getContext()).load(dataVideo.getThumb_pic()).into(vh.img);
}

@Override
public int getItemCount() {
    return (datas == null)? 0 : datas.getContent().size();
}

public class ViewHolder extends RecyclerView.ViewHolder{
    private ImageView img;
    private TextView tvTitle,tvArtis,tvPrice;

    public ViewHolder(@NonNull View itemView) {
        super(itemView);
        img = itemView.findViewById(R.id.imgVideo);
        tvArtis = itemView.findViewById(R.id.tvartis);
        tvTitle = itemView.findViewById(R.id.tvTitle);
        tvPrice = itemView.findViewById(R.id.tvPrice);
    }

}

}

он не должен возвращаться -1

Теги:
android-recyclerview
onclick

3 ответа

1
Лучший ответ

Внутри вашего ViewHolder вам нужно применить setOnClickListener и получить позицию элемента по клику с помощью getAdapterPosition() как getAdapterPosition() ниже

    public class ViewHolder extends RecyclerView.ViewHolder{
        private ImageView img;
        private TextView tvTitle,tvArtis,tvPrice;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            img = itemView.findViewById(R.id.imgVideo);
            tvArtis = itemView.findViewById(R.id.tvartis);
            tvTitle = itemView.findViewById(R.id.tvTitle);
            tvPrice = itemView.findViewById(R.id.tvPrice);
            YOUR_VIEW.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Toast.makeText(mContext,"Position==>> "+getAdapterPosition(),Toast.LENGTH_LONG).show();

                    DataVideo video = datas.getContent().get(viewHolder.getAdapterPosition()); // ERROR HERE
                    Intent intent = new Intent(context,DetailActivity.class);
                    intent.putExtra("datas",video);
                    context.startActivity(intent);

                }
            });
    }
}
0

Переместите свой клик в onBindViewHolder. Здесь он будет работать для клика по заголовку, если вы хотите, чтобы все клики делали макет виджета завершенным и реализовывали прослушиватель кликов.

 @Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
DataVideo dataVideo = datas.getContent().get(position);
ViewHolder vh = (ViewHolder)viewHolder;
vh.tvTitle.setText(dataVideo.getJudul());
vh.tvArtis.setText(dataVideo.getAlias());
vh.tvPrice.setText((dataVideo.getPrice().equals("0")?"Gratis":dataVideo.getPrice()));
Glide.with(vh.img.getContext()).load(dataVideo.getThumb_pic()).into(vh.img);
 vh.tvTitle.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {

        Intent intent = new Intent(context,DetailActivity.class);
        intent.putExtra("datas",dataVideo );
        context.startActivity(intent);
    }
});
}
  • 0
    многие говорят, что внедрение onclick внутри onBind не является лучшей практикой, см. stackoverflow.com/a/28904678/7201326
  • 0
    @ Asqa там получить положение отличается на onBindViewHolder и onCreateViewHolder
0

На самом деле, проблема только в том, что вы регистрируете прослушиватель кликов в вашем onCreateViewHolder, что неправильно, вам нужно зарегистрироваться на слушателе кликов в вашем onBindViewHolder, как показано ниже

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
    DataVideo dataVideo = datas.getContent().get(position);
    ViewHolder vh = (ViewHolder)viewHolder;
    vh.tvTitle.setText(dataVideo.getJudul());
    vh.tvArtis.setText(dataVideo.getAlias());
    vh.tvPrice.setText((dataVideo.getPrice().equals("0")?"Gratis":dataVideo.getPrice()));
    Glide.with(vh.img.getContext()).load(dataVideo.getThumb_pic()).into(vh.img);
vh.parentView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            Intent intent = new Intent(context,DetailActivity.class);
            intent.putExtra("datas",dataVideo);
            context.startActivity(intent);
        }
    });
}
  • 0
    многие говорят, что внедрение onclick внутри onBind не является лучшей практикой, см. stackoverflow.com/a/28904678/7201326

Ещё вопросы

Сообщество Overcoder
Наверх
Меню