如何从Firebase实时数据库为聊天应用程序更新Recyclerview

时间:2020-07-06 20:24:05

标签: android firebase firebase-realtime-database

我正在一起使用recyclerview和firebase实时数据库,以允许用户向其他用户发送消息。发送消息后,我需要再次启动该活动以重新加载更新。无论如何,有没有自动执行此操作的功能,因此当用户单击“发送”,将直接显示该消息。

点击发送按钮时的操作


 sendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {


                String message = messageBox.getText().toString();
                if (message.equals("")){
                    Toast.makeText(privatemessageactivity.this, "You cant send an empty message", Toast.LENGTH_SHORT).show();
                }else{


                    messagedref.addListenerForSingleValueEvent(new ValueEventListener() {
                        @Override
                        public void onDataChange(@NonNull DataSnapshot snapshot) {
                            if (!snapshot.exists()){
                                messagedref.setValue(true);
                            }
                        }

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

                        }
                    });



                    Map<String,Object> mymessage = new HashMap<>();
                    mymessage.put("Image",myImage);
                    mymessage.put("Message",message);
                    sendmessageref.push().setValue(mymessage);
                }
            }
        });


检索数据的操作


sendmessageref.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                if (snapshot.exists()){
                    for (DataSnapshot snapshot1 : snapshot.getChildren()){
                        MessageClass ld = snapshot1.getValue(MessageClass.class);
                        list.add(ld);
                    }

                    adapter = new MessageAdapter(list);
                    recyclerView.setAdapter(adapter);
                }
            }

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

            }
        });

我的适配器类和ViewHolder类


public class MessageAdapter extends RecyclerView.Adapter<MessageAdapter.ViewHolder>{

        private List<MessageClass> list;

        public MessageAdapter(List<MessageClass> list) {
            this.list = list;
        }

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

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

            MessageClass ld = list.get(position);
            holder.message.setText(ld.getMessage());

            if (!ld.getImage().equals("noimage")){
                Glide.with(getApplicationContext()).load(ld.getImage()).into(holder.circleImageView);
            }else{
                Glide.with(getApplicationContext()).load(R.drawable.profile).into(holder.circleImageView);
            }

        }

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

        public class ViewHolder extends RecyclerView.ViewHolder{

            TextView message;
            CircleImageView circleImageView;

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

                message = itemView.findViewById(R.id.messagesmessage);
                circleImageView = itemView.findViewById(R.id.messagespp);

            }
        }
    }

1 个答案:

答案 0 :(得分:0)

使用Firebase的整个目的是您不必显式重新加载消息。如果您使用addValueEventListener而不是addListenerForSingleValueEvent,Firebase将继续监听服务器上的更改,如果有任何更改,它将再次调用您的onDataChange

因此,使邮件列表保持最新状态的常用方法是:

adapter = new MessageAdapter(list);
recyclerView.setAdapter(adapter);

sendmessageref.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot snapshot) {
        list.clear();
        for (DataSnapshot snapshot1 : snapshot.getChildren()){
            MessageClass ld = snapshot1.getValue(MessageClass.class);
            list.add(ld);
        }
        adapter.notifyDataSetChanged();
    }

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

更改:

  • 使用addValueEventListener代替addListenerForSingleValueEvent,以便在初始数据和发生更改时都调用它。
  • onDataChange之外创建和分配适配器,因为您只希望设置一次适配器,然后更新其数据。
  • 清除onDataChange中的列表,因为我们现在将被多次调用,并且每次获得所有相关数据的完整DataSnapshot
  • 使用adapter.notifyDataSetChanged()通知适配器新数据,以便刷新UI。
  • 实施onCancelled,因为忽略可能的错误是一种不好的做法。
相关问题