Skip to content

Using If in RecyclerView, doesnt show all the item of the list

I am trying create a RecycleView for my chat application and to align the sent and arrived messages to the left and right. I used an if state to check if that is from me, and 2 separated textview aligned to start/end and only showing the correct one. I think it isn’t the best solution as sometimes after notifying the view about new data, the RecycleView doesn’t show all the items. If I just use it without any if/gone etc, the list showing correct number of the items.

 if (chats.get(position).isFromMe() > 0) {
                holder.txtTextFrMe.setText(chats.get(position).getMessage());
                holder.txtTimeOut.setText(timeForm);
                holder.relIn.setVisibility(View.GONE);
            } else {
                holder.txtText.setText(chats.get(position).getMessage());
                holder.txtTimeIn.setText(timeForm);
                holder.relOut.setVisibility(View.GONE);
            }

and the xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"

    android:orientation="vertical"
    android:padding="5dp">


    <RelativeLayout
        android:id="@+id/chatRelIn"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/chatText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentStart="true"
            android:background="@drawable/shape_bg_incoming_bubble"
            android:paddingVertical="10dp"
            android:paddingLeft="30dp"
            android:text="This is a message to me"
            android:paddingRight="10dp"
            android:textSize="17sp" />

        <TextView
            android:id="@+id/chatTextTimeIn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="10.21"
            android:layout_alignBottom="@id/chatText"
            android:layout_marginRight="10dp"
            android:layout_alignParentEnd="true"/>

    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/chatRelOut"
        android:layout_marginTop="15dp"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        android:gravity="right">

        <TextView
            android:id="@+id/chatTextFrMe"
            android:paddingLeft="10dp"
            android:paddingVertical="10dp"
            android:paddingRight="30dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/shape_bg_outgoing_bubble"
            android:textSize="17sp"
            android:layout_alignParentEnd="true"
            android:text="Message from me"
            />

        <TextView
            android:id="@+id/chatTextTimeOut"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="10.21"
            android:layout_alignBottom="@id/chatTextFrMe"
            android:layout_alignParentStart="true"
            android:layout_marginRight="10dp"

            />
    </RelativeLayout>
</LinearLayout>

Thanks in advance!

Answer

This is mainly because the recyclerview widget actually works with cache. That’s why you should repeat the same process for things that the user will see, such as GONE or VISIBLE.

if (chats.get(position).isFromMe() > 0) {
            holder.txtTextFrMe.setText(chats.get(position).getMessage());
            holder.txtTimeOut.setText(timeForm);
            holder.relIn.setVisibility(View.GONE);
            holder.relOut.setVisibility(View.VISIBLE);
        } else {
            holder.txtText.setText(chats.get(position).getMessage());
            holder.txtTimeIn.setText(timeForm);
            holder.relIn.setVisibility(View.VISIBLE);
            holder.relOut.setVisibility(View.GONE);
        }