Firebase的ListView聊天消息

时间:2018-08-01 21:47:30

标签: java android firebase listview firebase-realtime-database

我创建了一个涉及与其他人聊天的应用程序,为了使聊天活动更加令人愉悦,我创建了ListView来更改每条消息的UI。当我发送一条消息时,第一条消息会出现并正确显示,但是如果我发送另一条消息,它将覆盖listView中的上一条消息,而不仅仅是在列表视图中添加另一个值,这是我的代码:

ChatActivty:

private void append_chat_conversation(DataSnapshot dataSnapshot) {
        for (DataSnapshot ds : dataSnapshot.getChildren()) {
            Log.e("Chat details: ", String.valueOf(ds));
            chat_username = dataSnapshot.child("username").getValue(String.class);
            chat_msg = dataSnapshot.child("message").getValue(String.class);

            Chat chat = new Chat(chat_username, chat_msg);
            ArrayList<Chat> chatList = new ArrayList<>();
            chatList.add(chat);

            chatListAdapter adapter = new chatListAdapter(this, R.layout.chat_message, chatList);
            mListView.setAdapter(adapter);
            Log.e("Chat username: ", "" + chat_username);
            Log.e("Chat message: ", "" + chat_msg);

        }
}

聊天列表适配器:

public class chatListAdapter extends ArrayAdapter<Chat> {

    private Context mContext;
    int mResource;
    TextView usernameTV, messageTV;

    public chatListAdapter(Context context, int resource, ArrayList<Chat> objects) {
        super(context, resource, objects);
        mContext = context;
        mResource = resource;

    }

    @NonNull
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        String username = getItem(position).getUsername();
        String message = getItem(position).getMessage();

        Chat chat = new Chat(username, message);

        LayoutInflater inflater = LayoutInflater.from(mContext);
        convertView = inflater.inflate(mResource, parent, false);

        usernameTV = convertView.findViewById(R.id.username_chat);
        messageTV = convertView.findViewById(R.id.message_chat);

        usernameTV.setText(username);
        messageTV.setText(message);

        return convertView;
    }
}

我不会添加其他代码(getter和setter或单个消息的实际布局),因为我认为这不是问题。让我知道您是否还有其他需要,我确定我在做一些愚蠢的事情来实现这一目标,

谢谢,内森

编辑:

我终于找到了如何添加到列表视图中而不用以下代码覆盖它:

private void append_chat_conversation(DataSnapshot dataSnapshot) {
        for (DataSnapshot ds : dataSnapshot.getChildren()) {
            Log.e("Chat details: ", String.valueOf(ds));
            chat_username = dataSnapshot.child("username").getValue(String.class);
            chat_msg = dataSnapshot.child("message").getValue(String.class);

            Chat chat = new Chat(chat_username, chat_msg);
            chatList.add(chat);
            Log.e("Chat username: ", "" + chat_username);
            Log.e("Chat message: ", "" + chat_msg);
        }
        adapter.notifyDataSetChanged();
    }

,数组列表和adpater是顶部的公共变量,但是仍然显示两次消息。我仍然需要找到解决办法。感谢您的帮助

3 个答案:

答案 0 :(得分:1)

您可以使用FirebaseListAdapter来显示来自Firebase的消息,并将自定义布局应用于列表中的消息。

    FirebaseDatabase database = FirebaseDatabase.getInstance();
    Query messages = database.getReference("chatrooms").child(sessionId).child("messages");

    FirebaseListOptions<Message> options = new FirebaseListOptions.Builder<Message>().setQuery(messages, Message.class).setLayout(R.layout.message).build();

    ListView messageList = chatActivity.findViewById(R.id.message_list);
    adapter = new FirebaseListAdapter<Message>(options){
        @Override
        protected void populateView(View v, Message model, int position) {
            // Get references to the views of message.xml
            TextView messageText = v.findViewById(R.id.message_text);
            TextView messageUser = v.findViewById(R.id.message_user);
            TextView messageTime = v.findViewById(R.id.message_time);

            // Set their text
            messageText.setText(model.getMessageBody());
            messageUser.setText(model.getUser());

            // Format the date before showing it
            messageTime.setText(DateFormat.format("dd-MM-yyyy (HH:mm:ss)",
                    model.getTime()));
        }
    };

    messageList.setAdapter(adapter);
    adapter.startListening();

在此处查看更多信息:https://code.tutsplus.com/tutorials/how-to-create-an-android-chat-app-using-firebase--cms-27397

答案 1 :(得分:0)

尝试像这样重新安排:

private void append_chat_conversation(DataSnapshot dataSnapshot) {
    ArrayList<Chat> chatList = new ArrayList<>();
    for (DataSnapshot ds : dataSnapshot.getChildren()) {
        Log.e("Chat details: ", String.valueOf(ds));
        chat_username = dataSnapshot.child("username").getValue(String.class);
        chat_msg = dataSnapshot.child("message").getValue(String.class);

        Chat chat = new Chat(chat_username, chat_msg);
        chatList.add(chat);
        Log.e("Chat username: ", "" + chat_username);
        Log.e("Chat message: ", "" + chat_msg);
    }
    chatListAdapter adapter = new chatListAdapter(this, R.layout.chat_message, chatList);
    mListView.setAdapter(adapter);
}

编辑:

private void append_chat_conversation(DataSnapshot dataSnapshot) {
    chatListAdapter adapter = (chatListAdapter)mListView.getAdapter();

    chat_username = dataSnapshot.child("username").getValue(String.class);
    chat_msg = dataSnapshot.child("message").getValue(String.class);
    Log.e("Chat username: ", "" + chat_username);
    Log.e("Chat message: ", "" + chat_msg);
    Chat chat = new Chat(chat_username, chat_msg);

    adapter.add(chat);
    adapter.notifyDataSetChanged();
}

答案 2 :(得分:0)

要解决此问题,只需使用以下几行代码:

private void append_chat_conversation(DataSnapshot dataSnapshot) {
        ArrayList<Chat> chatList = new ArrayList<>();
        for (DataSnapshot ds : dataSnapshot.getChildren()) {
            chatList.add(ds.getValue(Chat.class));
        }
        chatListAdapter adapter = new chatListAdapter(this, R.layout.chat_message, chatList);
        mListView.setAdapter(adapter);
}

您的代码中的问题是您每次迭代都创建一个ArrayList的新实例,最终每次列表中只有一个项目。

编辑:

看到这一点,您的数据库引用应如下所示:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference keyRef = rootRef.child("matches").child("1").child("-LluNpbfFgzFclI7cdAS").child("messages");