Индекс RecyclerView = -1 при быстрой прокрутке вниз - PullRequest
1 голос
/ 11 июля 2020

Я создал RecyclerView для отображения элементов, и все отображается и работает нормально, за исключением одного сценария: когда я быстро прокручиваю до нижней части RecyclerView.

Если я это сделаю, я получаю следующая ошибка:

java.lang.ArrayIndexOutOfBoundsException: length=15; index=-1

Он направляет меня к этой части моего кода (в частности, к checkIfBorrowed.get( getAdapterPosition() )):

public class itemtestAdapter extends RecyclerView.Adapter<itemtestAdapter.testViewHolder> {

    private List<Discoveritems> items;
    private List<Boolean> checkIftested;

    interface OnItemCheckListener {
        void onItemCheck(Discoveritems items);
        void onItemUncheck(Discoveritems items);
    }

    @NonNull
    private OnItemCheckListener onItemCheckListener;

    public itemtestAdapter(List<Discoveritems> items, List<Boolean> checkIftested, @NonNull OnItemCheckListener onItemCheckListener) {
        this.items = items;
        this.onItemCheckListener = onItemCheckListener;
        this.checkIftested = checkIftested;
    }

    @Override
    public testViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view;
        view = LayoutInflater.from(parent.getContext()).inflate( R.layout.item_item_test_list, parent, false );
        return new testViewHolder(view);
    }

    @Override
    public void onBindViewHolder(testViewHolder holder, int position) {
        holder.bind(items.get(position));

        final Discoveritems currentItem = items.get(position);

        holder.setOnClickListener( v -> {
            holder.Cb_test.setChecked(
                    !holder.Cb_test.isChecked());
            if (holder.Cb_test.isChecked()) {
                onItemCheckListener.onItemCheck(currentItem);
            } else {
                onItemCheckListener.onItemUncheck(currentItem);
            }
        } );

    }

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

    class testViewHolder extends RecyclerView.ViewHolder {
        ImageView Iv_test,itemPic;
        TextView itemName;
        CheckBox Cb_test;
        Discoveritems items;

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

            Iv_testitemPic = itemView.findViewById(R.id.iv_itemCover);
            Tv_testitemName = itemView.findViewById( R.id.tv_testeditemName);
            Cb_test = itemView.findViewById( R.id.cb_testitem );
            Cb_test.setClickable( false );

        }

        public void setOnClickListener(View.OnClickListener onClickListener) {
            itemView.setOnClickListener(onClickListener);
        }

        public void bind(Discoveritems items) {

            this.items = items;

            String itemID = items.getitemID();
            MyitemClient client = new MyitemClient();
            client.getitems(itemID, new JsonHttpResponseHandler(){
                @Override
                public void onSuccess(int statusCode, Header[] headers, JSONObject response){
                    if(response!=null){
                        final Myitem items = Myitem.fromJson(response);

                        if (checkIftested.get( getAdapterPosition() )){
                            itemView.setEnabled(false);
                            Tv_itemName.setText("my" + items.getTitle());
                        } else {
                            Tv_itemName.setText( items.getTitle() );
                        }
                    }
                }

            });
            
        }
    }

}

Дело в том, что внутри привязки я не могу понять как получить позицию элемента без использования getAdapterPosition, и я также не могу понять, почему это происходит только при быстрой прокрутке.

Также странно, что он говорит length = 15, а размер checkIfBorowed равен только 12. Спасибо

1 Ответ

1 голос
/ 12 июля 2020

Измените holder.bind(items.get(position)); на holder.bind(items.get(position), position);, а затем измените метод просмотра bind, чтобы принять новый аргумент позиции, т.е. bind(Discoveritems items, int position) и использовать позицию вместо getAdapterPosition().

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

...