Данные RecyclerView перемещаются к другим элементам при прокрутке или добавлении нового элемента

#android #android-recyclerview

#Android #android-recyclerview -просмотр вторсырья #android-recyclerview

Вопрос:

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

Я успешно создал функцию добавления нового элемента, и она хранит данные с помощью TextWatcher in onBindViewHolder() . И данные TextView сохраняются в порядке.

Это onBindViewHolder() :

     @Override
    public void onBindViewHolder(@NonNull final EditMessageViewHolder holder, final int position) {
        MessageItem item = items.get(position);
        holder.messageET.setText(item.getMessage());
        holder.messageET.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                items.get(position).setMessage(charSequence.toString());
            }

            @Override
            public void afterTextChanged(Editable editable) {

            }
        });
    }
  

Это есть addItem() и getMessageItem() в адаптере:

     public void addItem(MessageItem messageItem) {
        items.add(messageItem);
        notifyItemInserted(items.size());
    }

    public ArrayList<MessageItem> getMessageItems() {
        return items;
    }
  

Однако проблема возникает, когда я добавляю дополнительные элементы или прокручиваю вверх или вниз. Данные смешиваются в неправильных порядках и неверных данных. Как я могу справиться с этой проблемой и как я могу предотвратить эту проблему также с помощью CheckBox и ImageView?

Ответ №1:

Я думаю, вместо того, чтобы использовать position в вашем onBindViewHolder (), попробуйте использовать adapter position. Что могло бы решить вашу проблему.

 MessageItem item = items.get(position);
  

Вместо этого используйте

 MessageItem item = items.get(holder.adapterPosition);
  

Дайте мне знать, если это сработает.

Если это не сработает, попробуйте использовать notifyItemInsertedRange вместо notifyiteminserted.

Спасибо

Комментарии:

1. Где я могу достать adapterPosition ? Параметры просто holder и position .

2. holder.adapterPosition @c-an . и попробуйте это и дайте мне знать, работает это или нет?

3. Я думаю, это работает! Спасибо. В чем разница?? В чем была проблема?

Ответ №2:

Вы пробовали метод setHasFixedSized (true) или setHasStableIds (true)?

Первый метод позволит RecyclerView избежать аннулирования всего макета при изменении содержимого его адаптера. Второй метод устанавливает стабильные идентификаторы для каждого элемента.

Комментарии:

1. Нет, я никогда не пробовал setHasFixedSized(true) или setHasStableIds(true) . Куда я должен поместить методы? В действии? или какая часть в адаптере?

2. Вы можете использовать в activity / fragment подобным образом yourRecylerView.setHasFixedSize(true); после настройки вашего адаптера на recyclerview

3. как насчет setHasStableIds(true) ?

4. setHasFixedSized(true) фиксирует высоту. Мне это не нужно, потому что RecyclerView можно прокручивать. Когда я добавляю новый элемент, высота не меняется. чего я совсем не хотел.