从recyclerview中删除消息

rkkpypqq  于 2021-08-20  发布在  Java
关注(0)|答案(2)|浏览(381)

我有一个发送消息的应用程序。
我想实现删除消息的功能。如果长时间单击邮件,则会出现一个标记的复选框。接下来,用户可以选择要删除的所有消息,然后单击垃圾箱图标。

这些消息是使用recyclerview实现的。使用livedata和room。
以下是listadapter的外观:

package com.mardaunt.telesupp.recyclerview;

import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.ListAdapter;
import com.mardaunt.telesupp.R;
import com.mardaunt.telesupp.room.Message;
import com.mardaunt.telesupp.room.TimeStampConverter;

public class MessageListAdapter extends ListAdapter<Message, MessageViewHolder> {

    public MessageListAdapter(@NonNull DiffUtil.ItemCallback<Message> diffCallback) {
        super(diffCallback);
    }

    @Override
    public int getItemViewType(int position) {
        if (getItem(position).getNature().equals("outgoing"))
            return R.layout.recyclerview_item_outgoing;
        else
            return R.layout.recyclerview_item_incoming;
    }

    @Override
    public MessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return MessageViewHolder.create(parent, viewType);
    }

    @Override
    public void onBindViewHolder(MessageViewHolder holder, int position) {
        Message current = getItem(position);

        holder.bind(current.getPhone(),
                    current.getText(),
                    TimeStampConverter.getTime(current.getDate())); // Бинтим телефон сообщение и время.
    }

    public static class MessageDiff extends DiffUtil.ItemCallback<Message> {

        @Override
        public boolean areItemsTheSame(@NonNull Message oldItem, @NonNull Message newItem) {
            return oldItem == newItem;
        }

        @Override
        public boolean areContentsTheSame(@NonNull Message oldItem, @NonNull Message newItem) {
            return oldItem.getText().equals(newItem.getText());
        }
    }
}

这是viewholder的外观:

package com.mardaunt.telesupp.recyclerview;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import com.mardaunt.telesupp.R;

class MessageViewHolder extends RecyclerView.ViewHolder {
    private final TextView phoneItemView;
    private final TextView messageItemView;
    private final TextView timeItemView;

    private MessageViewHolder(View itemView) {
        super(itemView);
        messageItemView = itemView.findViewById(R.id.text_view_message);
        phoneItemView = itemView.findViewById(R.id.text_view_phone);
        timeItemView = itemView.findViewById(R.id.text_view_time);
    }

    public void bind(String phone, String message, String time) {
        phoneItemView.setText(phone);
        messageItemView.setText(message);
        timeItemView.setText(time);
    }

        //viewType содержит id для нужного layout.
    static MessageViewHolder create(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                    .inflate(viewType, parent, false);
        return new MessageViewHolder(view);
    }
}

请告诉我如何才能正确开始这项任务?如果我想的没错,我需要在messagelistadapter类中设置一个长时间单击消息的侦听器。
github上的main活动。
应用程序的工作原型(apk文件)。

wko9yo5t

wko9yo5t1#

你可能需要一个中间对象,比如 MessageView ```
//this will allow each message to be selected individually.
//the adapter should display MessageViews instead of Messages directly.
public class MessageView{
private Message message;
private boolean isSelected;
//constructor and getters and setters;
}
//set your view holder like this
class MessageViewHolder extends RecyclerView.ViewHolder {
private final TextView phoneItemView;
private final TextView messageItemView;
private final TextView timeItemView;
private final Checkbox checkBoxView;

    private MessageViewHolder(View itemView) {
        super(itemView);
        messageItemView = itemView.findViewById(R.id.text_view_message);
        phoneItemView = itemView.findViewById(R.id.text_view_phone);
        timeItemView = itemView.findViewById(R.id.text_view_time);
        checkBoxView= itemView.findViewById(R.id.check_box_view);
        checkboxView.setOnCheckedChangeListener((checkbox,checked)=>{
             messageList.get(getAdapterPosition()).isSelected(checked);
        });
    }
    public void bind(MessageView messageView) {
         phoneItemView.setText(messageView.getMessage().getPhone());
         messageItemView.setText(messageView.getMessage().getMessage());
         timeItemView.setText(TimeStampConverter.getTime(messageView.getMessage().getDate()));
         checkBoxView.setChecked(messageView.isSelected());
    }
}  
//call this on the select all check box in your activity/fragment
public void onSelectAll(boolean selected){
    for(MessageView view : messageList)
         view.isSelected(selected);
    adapter.notifyDataSetChanged();
}
//call this on the delete all button click in your activity/fragment
public void onDeleteSelected(){
   Iterator i = messageList.iterator();
   MessageView messageView;
   while (i.hasNext()) {
      messageView = (MessageView ) i.next();
      if (messageView.isSelected())
        i.remove();
   }
   adapter.notifyDataSetChanged();   
}
bf1o4zei

bf1o4zei2#

我一直在想能做些什么。因此,我决定尝试为recyclerview中的每个元素添加复选框,并在listadapter类中设置侦听器。

public class MessageListAdapter extends ListAdapter<Message, MessageViewHolder> {

    HelperAdapter helperAdapter;

    public MessageListAdapter(@NonNull DiffUtil.ItemCallback<Message> diffCallback, HelperAdapter helperAdapter) {
        super(diffCallback);
        this.helperAdapter = helperAdapter;
    }

    @Override
    public int getItemViewType(int position) {
        if (getItem(position).getNature().equals("outgoing"))
            return R.layout.recyclerview_item_outgoing;
        else
            return R.layout.recyclerview_item_incoming;
    }

    @Override
    public MessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return MessageViewHolder.create(parent, viewType);
    }

    @Override
    public void onBindViewHolder(MessageViewHolder holder, int position) {
        Message current = getItem(position);

        holder.bind(current.getPhone(),
                    current.getText(),
                    TimeStampConverter.getTime(current.getDate())); // Бинтим телефон сообщение и время

            // Добавим все view CheckBox в list чтобы скрывать и показывать их по мере необходимости
        helperAdapter.addCheckBox(holder.getMessageCheckBox());

            // Установим слушатель короткого нажатия по сообщению.
        holder.getMessageBox().setOnClickListener(v -> {
            EditText editPhone = helperAdapter.getMainActivity()
                                    .findViewById(R.id.edit_phone);
            editPhone.setText(current.getPhone());
        });

            // Установим слушатель долгого нажатия по сообщению.
        holder.getMessageBox().setOnLongClickListener(v -> {
            helperAdapter.getMainActivity()
                         .findViewById(R.id.trash_button)
                         .setVisibility(View.VISIBLE);
            helperAdapter.getMainActivity()
                    .findViewById(R.id.close_button)
                    .setVisibility(View.VISIBLE);

            for (CheckBox checkBox: helperAdapter.getSetCheckBox())
                checkBox.setVisibility(View.VISIBLE);
            return false;
        });
            // Установим слушатели для чекбоксов, которые переключают переменную isSelected
        holder.getMessageCheckBox().setOnClickListener(v -> {
            current.isSelected = ((CheckBox) v).isChecked();

            helperAdapter.addCheckBox((CheckBox) v);
        });
    }

    public static class MessageDiff extends DiffUtil.ItemCallback<Message> {

        @Override
        public boolean areItemsTheSame(@NonNull Message oldItem, @NonNull Message newItem) {
            return oldItem == newItem;
        }

        @Override
        public boolean areContentsTheSame(@NonNull Message oldItem, @NonNull Message newItem) {
            return oldItem.getText().equals(newItem.getText());
        }
    }
}

我还创建了一个辅助类helperadapter,通过它删除标记的消息。

public class HelperAdapter {

    private static HelperAdapter helperAdapter;
    private MessageViewModel mMessageViewModel;
    private MainActivity mainActivity;
    private final HashSet<CheckBox> listCheckBox = new HashSet<>();

    public void deleteSelected() {
        LiveData<List<Message>> temp = mMessageViewModel.getAllMessages();
        List<Message> allMessages = temp.getValue();

        if (allMessages != null)
        for(Message message: allMessages)
            if(message.isSelected)
                mMessageViewModel.delete(message);

        // Скроем иконку корзины и чекбоксы
        mainActivity.findViewById(R.id.trash_button).setVisibility(View.GONE);
        mainActivity.findViewById(R.id.close_button).setVisibility(View.GONE);
        for (CheckBox checkBox: listCheckBox)
            checkBox.setVisibility(View.GONE);
    }

    public void setMessageViewModel(MessageViewModel messageViewModel){
        mMessageViewModel = messageViewModel;
    }

    public MessageViewModel getMessageViewModel() { return mMessageViewModel; }

    public HashSet<CheckBox> getSetCheckBox() {return listCheckBox;}

    public void addCheckBox(CheckBox checkBox) {
        listCheckBox.add(checkBox);
    }

    public void removeCheckBox(CheckBox checkBox){
        listCheckBox.remove(checkBox);
    }

    public int sizeCheckBox() {return listCheckBox.size();}

    public static HelperAdapter getHelperAdapter(){
        if (helperAdapter == null) helperAdapter = new HelperAdapter();
        return helperAdapter;
    }

    public void setMainActivity(MainActivity mainActivity){
        this.mainActivity = mainActivity;
    }

    public MainActivity getMainActivity() { return mainActivity; }
}

我还为message类添加了一个布尔变量:

@Entity(tableName = "messages_table")
public class Message {

    @PrimaryKey(autoGenerate = true)
    private int id;
    private String phone;
    private String text;
    private String nature;
    private String service;
    private Date date;

    @Ignore
    public boolean isSelected;   // I added it

    public Message(int id,
                   @NonNull String phone,
                   @NonNull String text,
                   @NonNull String nature,
                   @NonNull String service,
                   @NonNull Date date
                    ) {
        this.id = id;
        this.phone = phone;
        this.text = text;
        this.nature = nature;
        this.service = service;
        this.date = date;
    }

    public int getId(){return this.id;}
    public String getPhone(){return this.phone;}
    public String getText(){return this.text;}
    public String getNature(){return this.nature;}
    public String getService(){return this.service;}
    public Date getDate(){return this.date;}
}

现在,我可以设置垃圾桶图标的侦听器:

// ОнКлик для иконки корзины
    public void deleteMessage(View view){
        helperAdapter.deleteSelected();
    }

多亏了livedata,我不必考虑更新recyclerview。livedata删除已删除的邮件。
这或多或少是稳定的,但我有一种感觉,我把架构搞砸了,选择了错误的方法。
测试apk文件:https://dropmefiles.com/uxppx

相关问题