簡體   English   中英

每次我添加新項目時,RecyclerView 都會填充每個項目

[英]RecyclerView populating each item every time i add a new item

我正在嘗試制作一個副本聊天應用程序,並且我有一個需要填充到回收站視圖中的列表。 我從 firebase 實時數據庫中獲取數據,每次我收到或實際發送消息時,所有以前的項目(消息)加上新的項目都會重新填充/復制到回收站視圖中。

我嘗試過在向列表中添加新項目之前在列表中使用.cleaar()方法,但現在回收站視圖中的所有其他項目都消失了

這是我的適配器

public class MessageAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    public static final int MSG_TYPE_LEFT = 0;
    public static final int MSG_TYPE_RIGHT = 1;
    FirebaseUser firebaseUser;


    private Context ctx;
    private List<Messages> msgsR, msgsS;//ignore unused
    private ArrayList<Messages> dataSet;

    public MessageAdapter(Context context) {
        this.ctx = context;
        this.dataSet = new ArrayList<>();
        //this.msgsR = messagesReceived;
    }


    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if (viewType == Messages.SENT_TYPE) {
            View view = LayoutInflater.from(ctx).inflate(R.layout.message_item_right, parent, false);
            return new ViewHolderS(view);
        }
        if (viewType == Messages.RECEIVED_TYPE) {
            View view = LayoutInflater.from(ctx).inflate(R.layout.message_item_left, parent, false);
            return new ViewHolderR(view);
        }
        return null;
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {

        Messages object = dataSet.get(position);
        if (object != null) {
            switch (object.type) {
                case Messages.RECEIVED_TYPE:
                    ((ViewHolderR) holder).populate(object, position);
                    break;
                case Messages.SENT_TYPE:
                    ((ViewHolderS) holder).populate(object, position);
                    break;
            }
        }


    }
//recceives messages object to populate into list
//it does not matter where i put the .clear() method, after or below dataset.add() its still undesireable
    public void addMessageSent(Messages messages){
        dataSet.clear();
        dataSet.add(messages);
       // notifyItemInserted(dataSet.size()-1);
        //notifyItemRangeChanged(dataSet.size()-1, dataSet.size());

    }

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

    // sent messages are handled here
    public static class ViewHolderS extends RecyclerView.ViewHolder {
        public TextView msg, time;
        public LinearLayout layout;

        public ViewHolderS(@NonNull View itemView) {
            super(itemView);

            layout = itemView.findViewById(R.id.cont);
            msg = itemView.findViewById(R.id.send_msg);
            time = itemView.findViewById(R.id.time);

        }

        private void populate(Messages messages, int position) {
            msg.setText(messages.getMessage());
            msg.setPadding(6, 4, 18, 4);
            msg.setMinWidth(100);
            msg.setMaxWidth(400);
            LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) msg.getLayoutParams();
            layoutParams.gravity = Gravity.START;
            layoutParams.width = LinearLayout.LayoutParams.WRAP_CONTENT;
            layoutParams.height = LinearLayout.LayoutParams.WRAP_CONTENT;
            layoutParams.topMargin = layoutParams.bottomMargin = layoutParams.rightMargin = 10;
            layoutParams.leftMargin = 20;

            msg.setLayoutParams(layoutParams);
            time.setText(messages.getTime());
        }
    }

    @Override
    public int getItemViewType(int position) {
        switch (dataSet.get(position).type) {
            case 0:
                return Messages.SENT_TYPE;
            case 1:
                return Messages.RECEIVED_TYPE;

            default:
                return -1;
        }

       
    }

// received messages are handled here
    private class ViewHolderR extends ViewHolderS {
        public TextView msg, time;
        public LinearLayout layout;

        public ViewHolderR(@NonNull View itemView) {
            super(itemView);
            layout = itemView.findViewById(R.id.cont);
            msg = itemView.findViewById(R.id.send_msg);
            time = itemView.findViewById(R.id.time);
        }

        private void populate(Messages messages, int position) {

            msg.setText(messages.getMessage());
            msg.setPadding(6, 4, 18, 4);
            msg.setMinWidth(100);
            msg.setMaxWidth(400);
            LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) msg.getLayoutParams();
            layoutParams.gravity = Gravity.START;
            layoutParams.width = LinearLayout.LayoutParams.WRAP_CONTENT;
            layoutParams.height = LinearLayout.LayoutParams.WRAP_CONTENT;
            layoutParams.topMargin = layoutParams.bottomMargin = layoutParams.rightMargin = 10;
            layoutParams.leftMargin = 20;

            msg.setLayoutParams(layoutParams);
            time.setText(messages.getTime());
        }
    }
}

這是我的數據 model

public class Messages {
    private String message;
    public static final int SENT_TYPE=0;
    public static final int RECEIVED_TYPE=1;
    public static final int AUDIO_TYPE=2;
    private long time;
    public int type;

    private String id;
    private String receiver;

    public Messages(String message,long time, String sender,String receiver, int type) {
        this.message = message;
        this.time = time;
        this.id = sender;
        this.type = type;
        this.receiver = receiver;
    }

    public Messages() {
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public String getTime() {

        SimpleDateFormat output = new SimpleDateFormat("HH:mm", Locale.getDefault());
        return output.format(new Date(time));
    }

    public void setTime(long time) {
        this.time = time;
    }

    public String getSender() {
        return id;
    }

    public void setSender(String sender) {
        this.id = sender;
    }

    public String getReceiver() {
        return receiver;
    }

    public void setReceiver(String receiver) {
        this.receiver = receiver;
    }
}

以下是活動 class 我在其中設置適配器並填寫列表

recyclerView.setHasFixedSize(true);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getApplicationContext());
        linearLayoutManager.setStackFromEnd(true);
        recyclerView.setLayoutManager(linearLayoutManager);

list= new ArrayList();

        messageAdapter = new MessageAdapter(PersonChatActivity.this);
        recyclerView.setAdapter(messageAdapter);
        recyclerView.setItemAnimator(new DefaultItemAnimator());

if (Objects.requireNonNull(recyclerView.getAdapter()).getItemCount() > 0) {
            recyclerView.smoothScrollToPosition(recyclerView.getAdapter().getItemCount());
        }

//get sent messages from firebase
    private void getmessages() {
        DatabaseReference reference = database.getReference("Chats");
        reference.keepSynced(true);
        reference.child(senderId).child(receiver).push();
        reference.child(senderId).child(receiver).addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                messageSent.clear();
                for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
                    if (dataSnapshot.getValue() != null) {
                        String message = (String) dataSnapshot.child("message").getValue();
                        long time = (Long) dataSnapshot.child("time").getValue();
                        String senderId = (String) dataSnapshot.child("id").getValue();
                        String receiverId = (String) dataSnapshot.child("receiver").getValue();
                        assert firebaseUser != null;
                        String user = firebaseUser.getUid();
                        Messages msg = new Messages(message, time, senderId, receiverId,Messages.SENT_TYPE);
                        String Uid = msg.getSender();
                        if (!Uid.isEmpty() && Uid.equals(user)) {
//pass the new message object to messages adapter to fill the list
                           messageAdapter.addMessageSent(msg);
                        }

                    }
                }

            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {
            }
        });
    }

編輯更新

正如建議的那樣,我已經進行了必要的更改並且代碼像魔術一樣工作我不會將正確的更改更新到問題中,以防有人犯了與我相同的錯誤加上標記為答案的評論基本上突出了正確的更改,,

新問題新問題是,在將 object 消息添加到addMessagesent()之前填充的 recyclerview 項目被新數據替換。

為方便起見,在收到新消息時,所有以前可見的已發送消息都會消失並被新收到的消息取代

這是我的getmessageReceived()方法

        DatabaseReference reference = database.getReference("Chats");
        reference.keepSynced(true);
        reference.child(receiver).child(senderId).push();
        reference.child(receiver).child(senderId).addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                messageReceived.clear();
                messageAdapter.clearAllMessage();
                for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
                    if (dataSnapshot.getValue() != null) {
                        String message = (String) dataSnapshot.child("message").getValue();
                        long time = (Long) dataSnapshot.child("time").getValue();
                        String senderId = (String) dataSnapshot.child("id").getValue();
                        String receiverId = (String) dataSnapshot.child("receiver").getValue();
                        assert firebaseUser != null;
                        String user = firebaseUser.getUid();
                        Messages msg = new Messages(message, time, senderId, receiverId,Messages.RECEIVED_TYPE);
                        String Uid = msg.getReceiver();
                        if (!Uid.isEmpty() && Uid.equals(user)) {
                            messageAdapter.addMessageSent(msg);
                            messageAdapter.notifyDataSetChanged();

                        }
                    }

                }

            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {
            }
        });
    }

您不應該清除addMessageSent()中的數據集,只需將新項目添加到數據集中,如下所示

  public void addMessageSent(Messages messages){  
        dataSet.add(messages);
    }

並創建一個新方法來清除適配器中的數據集

public void clearAllMessage(){  
            dataSet.clear();
        }

在 getmessages() 中像這樣調用 clearAllMessage()

private void getmessages() {
        DatabaseReference reference = database.getReference("Chats");
        reference.keepSynced(true);
        reference.child(senderId).child(receiver).push();
        reference.child(senderId).child(receiver).addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                messageSent.clear();
                 clearAllMessage();
                for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
                    if (dataSnapshot.getValue() != null) {
                        String message = (String) dataSnapshot.child("message").getValue();
                        long time = (Long) dataSnapshot.child("time").getValue();
                        String senderId = (String) dataSnapshot.child("id").getValue();
                        String receiverId = (String) dataSnapshot.child("receiver").getValue();
                        assert firebaseUser != null;
                        String user = firebaseUser.getUid();
                        Messages msg = new Messages(message, time, senderId, receiverId,Messages.SENT_TYPE);
                        String Uid = msg.getSender();
                        if (!Uid.isEmpty() && Uid.equals(user)) {
//pass the new message object to messages adapter to fill the list
                           messageAdapter.addMessageSent(msg);
                           messageAdapter.notifyDataSetChanged();  // Call this also 
                        }

                    }
                }

            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {
            }
        });
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM