Обновление RecyclerView без обновления списка адаптеров - PullRequest
0 голосов
/ 09 мая 2020

Я пытаюсь создать приложение для чата, и когда я хочу добавить сообщение в свой собственный RecyclerView, затрагиваются все сообщения, и они изменятся (ОСОБЕННО при добавлении изображения).

Я попытался делаю notifyItemChanged(position), но стало еще хуже. Вот мой код адаптера:

 @NonNull
@Override
public MessageViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_message, null, false);
    FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);

    layoutView.setLayoutParams(lp);

    MessageViewHolder rcv = new MessageViewHolder(layoutView);
    return rcv;
}

@Override
public void onBindViewHolder(@NonNull final MessageViewHolder holder, final int position) {


    holder.mMessage.setText(messageList.get(position).getMessage());
    holder.mSender.setText(messageList.get(position).getSenderId());
    Picasso.Builder builder = new Picasso.Builder(context);
    builder.downloader(new OkHttp3Downloader(context));
    builder.build().load(messageList.get(position).getProfilePic())
            .placeholder((R.drawable.image))
            .into(holder.imgprofile);

    if(!messageList.get(holder.getAdapterPosition()).getMediaUrlList().isEmpty()){
        holder.mViewMedia.setVisibility(View.VISIBLE);
        Picasso.Builder builder2 = new Picasso.Builder(context);
        builder2.downloader(new OkHttp3Downloader(context));
        builder2.build().load(messageList.get(holder.getAdapterPosition()).getMediaUrlList().get(0))
                .placeholder((R.drawable.ic_launcher_background))
                .error(R.drawable.ic_launcher_background)
                .into(holder.mViewMedia);

    }


    holder.mViewMedia.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            new ImageViewer.Builder(v.getContext(), messageList.get(holder.getAdapterPosition()).getMediaUrlList())
                    .setStartPosition(0)
                    .show();
        }
    });

}

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





class MessageViewHolder extends RecyclerView.ViewHolder{
   //defining textviews and stuff..
    }
}

Буду рад, если у кого-нибудь появятся идеи.

Ответы [ 2 ]

0 голосов
/ 10 мая 2020

Сделайте ваш класс расширенным ListAdapter. Создайте переменную DiffUtil.ItemCallback. и передать его конструктору суперкласса. Остальные методы будут более или менее похожи по сравнению с использованием RecyclerView.Adapter.

Вот пример кода:

MessageAdapter. java

public class MessageAdapter extends ListAdapter<Model, MessageAdapter.MessageHolder> {
    private static final DiffUtil.ItemCallback<Model> DIFF_CALLBACK = new DiffUtil.ItemCallback<Model>() {
        @Override
        public boolean areItemsTheSame(@NonNull Model oldItem, @NonNull Model newItem) {
            return oldItem.getId() == newItem.getId();
        }

        @Override
        public boolean areContentsTheSame(@NonNull Model oldItem, @NonNull Model newItem) {
            return oldItem.getMessage().equals(newItem.getMessage()) &&
                    oldItem.getSeen().equals(newItem.getSeen()); //and other similar checks
        }
    };

    public MessageAdapter() {
        super(DIFF_CALLBACK);
    }

    @NonNull
    @Override
    public MessageHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.message_item, parent, false);
        return new MessageHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull MessageHolder holder, int position) {
        Message currentMessage = getItem(position);
        holder.messageTextview.setText(currentMessage.getMessage());
        holder.seenTextview.setText(currentMessage.getSeen());
        //further views
    }

    public Message getMessageAt(int position) {
        return getItem(position);
    }

    class MessageHolder extends RecyclerView.ViewHolder {
        private TextView messageTextview;
        private TextView seenTextview;
        //other views

        MessageHolder(@NonNull View itemView) {
            super(itemView);
            messageTextview = itemView.findViewById(R.id.message_tv);
            seenTextview = itemView.findViewById(R.id.seen_tv);

            //Register listeners if needed
        }
    }
}

И, наконец, отправьте свой список, используя объект этого класса адаптера. Например:

MessageAdapter adapter = new MessageAdapter();

//prepare list and submit using
adapter.submitList(list);

areItemsTheSame() должен реализовывать проверки, чтобы убедиться, что элементы в целом, которые накачаны, одинаковы. Принимая во внимание, что areContentsTheSame() должен реализовывать проверки, которые гарантируют, что содержимое внутри каждого элемента recyclerview не изменится.

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

0 голосов
/ 09 мая 2020

Я думаю, что в Android Библиотеке поддержки есть служебный класс с именем DiffUtil. Это обратный вызов, который обнаруживает изменения между двумя списками.

, вы можете обратиться к этому руководству: https://www.journaldev.com/20873/android-recyclerview-diffutil и https://medium.com/@iammert / using-diffutil-in- android -recyclerview-bdca8e4fbb00

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...