RecyclerView отображает дубликат первого элемента, когда список заполняет экран - PullRequest
0 голосов
/ 17 сентября 2018

У меня есть несколько элементов в ListItemView / RecyclerView.Когда элементы добавляются, они корректно обновляют представление, и элементы отображаются в порядке их добавления.

Однако, когда я перехожу несколько элементов, чтобы все виды заполняли экран (становится возможной прокрутка), он снова отображает первый элемент в виде дубликата вместо отображения последнего добавленного элемента.

Мой метод GetView:

@NonNull
@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View listItemView = convertView;

    Log.d(TAG, "The GetView method was called");

    ChatConversationMessage currentMessage = getItem(position);

    if (listItemView == null) {
        if (currentMessage.getSentTextMessage() != null) {

            Log.d(TAG, "Sent message detected");
            // Sent text
            listItemView = LayoutInflater.from(getContext()).inflate(
                    R.layout.chat_conversation_txt_sent, parent, false);
            TextView sentText = listItemView.findViewById(R.id.textview_chat_message_sent);
            sentText.setText(currentMessage.getSentTextMessage());
        }

        if (currentMessage.getReceivedTextMessage() != null) {

            Log.d(TAG, "Received message detected");
            // Received text
            listItemView = LayoutInflater.from(getContext()).inflate(
                    R.layout.chat_conversation_txt_received, parent, false);
            TextView receivedText = listItemView.findViewById(R.id.textview_chat_message_received);
            receivedText.setText(currentMessage.getReceivedTextMessage());
            ImageView chatHead = listItemView.findViewById(R.id.imageview_chat_head_received);
            chatHead.setImageResource(currentMessage.getImageResourceId());
            chatHead.setClipToOutline(true);
        }
    }

    return listItemView;
}

И мой метод getLiveMessages (из Firestore)

public void getLiveChatMessages(final ArrayList<ChatConversationMessage> messageArrayList, final ChatConversationMessageAdapter adapter) {

            messagesCollectionRef.addSnapshotListener(new EventListener<QuerySnapshot>() {
                @Override
                public void onEvent(@Nullable QuerySnapshot snapshots,
                                    @Nullable FirebaseFirestoreException e) {
                    if (e != null) {
                        Log.w(TAG, "listen:error", e);
                        return;
                    }

                    for (DocumentChange dc : snapshots.getDocumentChanges()) {

                        switch (dc.getType()) {
                            case ADDED:
                                Log.d(TAG, "New message added" + dc.getDocument().getData());

                                if (dc.getDocument().get("Message") != null && dc.getDocument().get("From user with ID").equals(userID)) {
                                    String message = dc.getDocument().getString("Message");
                                    messageArrayList.add(new ChatConversationMessage(message));
                                    adapter.notifyDataSetChanged(); //Ensures messages are visible immediately

                                } else if (dc.getDocument().get("Message") != null) {
                                    String message = dc.getDocument().getString("Message");
                                    Log.e("TAG", "The received message is written to the array. Message: " + message);
                                    messageArrayList.add(new ChatConversationMessage(message, R.drawable.redhead_1));

                                    adapter.notifyDataSetChanged(); //Ensures messages are visible immediately

                                }
                                Log.d(TAG, "Message ArrayList: " +  messageArrayList);
                                break;

                            case MODIFIED:
                                Log.d(TAG, "Message modified" + dc.getDocument().getData());
                                break;
                            case REMOVED:
                                Log.d(TAG, "Message removed" + dc.getDocument().getData());
                                break;
                        }
                    }

                }
            });
}

1 Ответ

0 голосов
/ 17 сентября 2018

Вы неправильно обрабатываете вид "переработка". getView() всегда должен возвращать представление и устанавливать значения подпредставления, последнее - то место, где у вас возникают проблемы.

Это аннотированный код, показывающий некоторые предложения по решению вашей проблемы:

public View getView(int position, View convertView, ViewGroup parent) {
    View listItemView = convertView;

    Log.d(TAG, "The GetView method was called");

    ChatConversationMessage currentMessage = getItem(position);

    // determine if Sent Message
    if (currentMessage.getSentTextMessage() != null) 
    {

        Log.d(TAG, "Sent message detected");

        if (listItemView == null) {
            // inflate the layout as needed
            listItemView = LayoutInflater.from(getContext()).inflate(
                    R.layout.chat_conversation_txt_sent, parent, false);
        }

        // now set the subview values
        TextView sentText = listItemView.findViewById(R.id.textview_chat_message_sent);
        sentText.setText(currentMessage.getSentTextMessage());
    }

    // else a Received Message
    else if (currentMessage.getReceivedTextMessage() != null) {

        Log.d(TAG, "Received message detected");

        if (listItemView == null) {
            // inflate the layout as needed
            listItemView = LayoutInflater.from(getContext()).inflate(
                    R.layout.chat_conversation_txt_received, parent, false);
        }

        // then set the subview values
        TextView receivedText =  listItemView.findViewById(R.id.textview_chat_message_received);
        receivedText.setText(currentMessage.getReceivedTextMessage());
        ImageView chatHead = listItemView.findViewById(R.id.imageview_chat_head_received);
        chatHead.setImageResource(currentMessage.getImageResourceId());
        chatHead.setClipToOutline(true);
    }

    return listItemView;
}

Вы должны рассмотреть ViewHolder для двух ваших макетов, это упростит ваш код и сделает его более эффективным во время выполнения. Не уверен, что это лучшая ссылка, но должен дать вам несколько дополнительных идей:

О RecyclerView.ViewHolder и RecyclerView.Adapter

...