简体   繁体   English

Firebase的ListView聊天消息

[英]ListView chat message for Firebase

I have created an app which involves chatting with other people, and to make the chat activity more pleasing to the eye I created a ListView to change the UI of each message. 我创建了一个涉及与其他人聊天的应用程序,为了使聊天活动更加令人愉悦,我创建了ListView来更改每个消息的UI。 When I send a message the first message appears and displays correctly but if I send another message it overrides the previous message in the listView instead of just adding another value to the list view, here's my code: 当我发送一条消息时,第一条消息会出现并正确显示,但是如果我发送另一条消息,它将覆盖listView中的上一条消息,而不仅仅是在列表视图中添加另一个值,这是我的代码:

ChatActivty: 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);

        }
}

Chat List adapter: 聊天列表适配器:

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;
    }
}

I won't add the other bits of code (the getter and setters or the actual layout of the individual messages) because I don't think that's a problem. 我不会添加其他代码(getter和setter或单个消息的实际布局),因为我认为这不是问题。 Let me know if you need anything else, I'm sure I'm doing something stupid here to make this happen, 让我知道您是否还有其他需要,我确定我在做一些愚蠢的事情来实现这一目标,

Thanks, Nathan 谢谢,内森

EDIT: 编辑:

I finally found out how to add to the listview without it overriding with this code: 我终于找到了如何添加到列表视图中而不用以下代码覆盖它:

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();
    }

with the array list and adpater being a public variable at the top, however it still shows the message twice. 数组列表和adpater是顶部的公共变量,但是仍然显示两次消息。 I still need to find a fix for that. 我仍然需要找到解决办法。 Thanks for the help 谢谢您的帮助

You can use a FirebaseListAdapter to display messages from firebase, and apply a custom layout to the messages in the list. 您可以使用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();

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

Try re-arrange like this: 尝试像这样重新安排:

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);
}

Edited: 编辑:

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();
}

To solve this, simply use only the following lines of code: 要解决此问题,只需使用以下几行代码:

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);
}

The problem in your code is that your are creating a new instance of an ArrayList at every iteration, ending up having everytime only one item in the list. 您的代码中的问题在于,您每次迭代都在创建一个ArrayList的新实例,最终每次列表中仅包含一项。

Edit: 编辑:

Seeing this, your database reference should look like this: 看到这一点,您的数据库引用应如下所示:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM