1

i'm here to ask if anyone knows a workaround to the issue i'm failing to fix.

Basically i'm coding a simple Chat App in Android using Firebase as an exercise. I'm using a ListView in my main layout and a simple Layout to use for each "message bubble". Here comes the problem: when i visualize the messages that i retrieve from Firebase i change the color of the bubble based on the current user in runtime, when first loaded each bubble has the right color, but by scrolling up and down my messages more and more bubbles take on the "ActiveUser" color even if they belong to different users, any ideas? I'll leave the code i'm using down below

Main Layout ListView

 <ListView
    android:id="@+id/list_of_messages"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_above="@id/inputArea"
    android:layout_alignParentStart="true"
    android:layout_alignParentTop="true"
    android:divider="@android:color/transparent"
    android:dividerHeight="16dp"
    android:paddingStart="15dp"
    android:paddingBottom="5dp"
    android:paddingEnd="15dp"
    android:paddingTop="10dp"/>

Message Bubble Layout

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:id="@+id/message_bubble"
android:background="@drawable/normal_message_background">

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_alignParentStart="true"
    android:id="@+id/message_user"
    android:textStyle="normal|bold" />

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_toEndOf="@id/message_user"
    android:layout_marginStart="10dp"
    android:id="@+id/message_time" />

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/message_user"
    android:layout_alignParentStart="true"
    android:layout_marginTop="5dp"
    android:id="@+id/message_text"
    android:textAppearance="@style/TextAppearance.AppCompat.Body1"
    android:textSize="18sp" />

FirebaseListAdapter and runtime style change code chunk

private void displayChatMessages() {

    ListView listOfMessages = findViewById(R.id.list_of_messages);

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

    mAdapter = new FirebaseListAdapter<ChatMessage>(options) {
        @Override
        protected void populateView(View v, ChatMessage model, int position) {
            // Get references to the views of message.xml

            RelativeLayout messageBubble = v.findViewById(R.id.message_bubble);
            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.getMessageText());
            messageUser.setText(model.getMessageUser());
            messageTime.setText(model.getMessageTime());

            if (messageUser.getText().equals(FirebaseAuth.getInstance().getCurrentUser().getDisplayName()))
                messageBubble.setBackgroundResource(R.drawable.active_user_message_background);

        }
    };

    listOfMessages.setAdapter(mAdapter);

}

EDIT: I've fixed the problem by declaring the else statement to set the normal drawable variant back if the usernames did not match, however once changed the background Resource in runtime the bubble looks smaller and doesn't wrap around all the text, does anyone know the reason of this?

2ND EDIT: I've found the solution to my second problem in this other post: Where'd padding go, when setting background Drawable?

Apparently the issue should have been fixed back in API 19/21, however if you still experience that problem apply the workaround explained in the thread linked above

LaXfar
  • 90
  • 6

1 Answers1

0

ListView will reuse views to help with performance. This means when we scroll the adapter will just place your content in a view that was slated to go off screen rather than inflating a new view. This is causing all views that you set the current user background on to always keep that background since you don't have a condition to set it back if the view is filled with non-current user data.

To fix this add the following condition:

if (messageUser.getText().equals(FirebaseAuth.getInstance().getCurrentUser().getDisplayName())){                
 messageBubble.setBackgroundResource(R.drawable.active_user_message_background);
}
else{
    messageBubble.setBackgroundResource(R.drawable.normal_message_background);
}
Joey Baker
  • 791
  • 5
  • 5
  • Yeah i've figured out that might work shortly after i've posted, but i still encounter the problem of the runtime set backgrounds to be smaller than the actual bubble layout, also would there be a better way to handle the background change given what i did so far? – LaXfar Jun 19 '18 at 14:43