0

I am working on a chat app using Firebase. to display messages, I am using a recyclerView and a FirebaseRecyclerAdapter for it. The problem is that I want to change the layout associated to this FirebaseRecyclerAdapter depending on the sender of the message so that the messages of the sender and receiver looks different, but I don't how to do this.

please if you have any idea let me know ! those are my onStart method and the viewHolder class and the layouts of the messages .

thanks guys.

protected void onStart() {
    super.onStart();
    FirebaseRecyclerAdapter<Message,MessageViewHolder> FBRA1 = new FirebaseRecyclerAdapter<Message, MessageViewHolder>(
            Message.class,
            R.layout.singlemessagelayout,
            MessageViewHolder.class,
            refbase1
    ) {
        @Override
        protected void populateViewHolder(MessageViewHolder viewHolder, Message model, int position) {
            try {
                viewHolder.setContent(model.getSender().username, model.message);
            }catch (NullPointerException e){

            }

        }
    } ;
    recyclerView.setAdapter(FBRA1);
    recyclerView.scrollToPosition(recyclerView.getAdapter().getItemCount());

}
public static class MessageViewHolder extends RecyclerView.ViewHolder {
    View v ;
    public MessageViewHolder(View itemView) {
        super(itemView);
        v = itemView ;
    }

    public void setContent(String username, String content) {
        TextView messageContent = (TextView)v.findViewById(R.id.emailid2) ;
        TextView messagesender = (TextView)v.findViewById(R.id.usernameid2) ;
        messageContent.setText(content);
        messagesender.setText(username);

    }
}

and this is my first message layout called "singlemessagelayout.xml"

       <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:background="@drawable/gradient2"
        android:layout_margin="10dp"
        android:id="@+id/mylayout"
        android:layout_alignParentRight="false"

        >
            <TextView
                android:layout_marginLeft="0dp"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="sender"
                android:textColor="#52EFFF"
                android:textStyle="italic"
                android:textSize="18dp"
                android:id="@+id/usernameid2"
                />
            <TextView
                android:layout_marginLeft="20dp"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="message envoyé"
                android:textSize="20dp"
                android:textStyle="bold"
                android:textColor="#ffffff"
                android:gravity="center"
                android:id="@+id/emailid2"
                />

    </LinearLayout>

and this is my second message layout called "singlemessagelayout2.xml"

       <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:background="@drawable/gradient2"
        android:layout_margin="10dp"
        android:id="@+id/mylayout"
        android:layout_alignParentRight="true"

        >
            <TextView
                android:layout_marginLeft="0dp"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="sender"
                android:textColor="#52EFFF"
                android:textStyle="italic"
                android:textSize="18dp"
                android:id="@+id/usernameid2"
                />
            <TextView
                android:layout_marginLeft="20dp"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="message envoyé"
                android:textSize="20dp"
                android:textStyle="bold"
                android:textColor="#ffffff"
                android:gravity="center"
                android:id="@+id/emailid2"
                />

    </LinearLayout>
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
AyoubS
  • 51
  • 8

2 Answers2

0

If you look at messaging apps you would notice the usability is given by placing the received messages on the left and the send messages on the right. That means you need to know if the message is sent from the current user, therefore your model should have an identifier. UID or email should do it. Something like this:

{
    "message": "hello world",
    "sender": UID1
}

To simplify the problem my solution is to use a single layout and then change the properties of the layout programmatically based on the identifier, if match the current user then it will go to the right, if not is a received message it will go to the left.

<?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">

    <TextView
        android:id="@+id/messageTv"
        android:layout_width="wrap_content"
        android:paddingStart="16dp"
        android:paddingEnd="16dp"
        android:paddingBottom="8dp"
        android:paddingTop="8dp"
        android:layout_height="wrap_content" />

</LinearLayout>

I'm using a LinearLayout as a container because found easier to set padding and gravity, but you could use something else.

The next chunk of code should go inside your populateViewHolder method

TextView textView = holder.textView;
textView.setText(model.getMessage());

LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) textView.getLayoutParams();
final Resources resources = textView.getContext().getResources();
int gravity;
int zero = 0;
int padding = (int) resources.getDimension(R.dimen.message_container_padding);
ViewGroup container = holder.container;

boolean isOwner = CURRENT_UID.equals(model.getSender());

if (isOwner) {
    gravity = Gravity.END;
    container.setPaddingRelative(padding, zero, zero, zero);
} else {
    gravity = Gravity.START;
    container.setPaddingRelative(zero, zero, padding, zero);
}
textView.setGravity(gravity);
layoutParams.gravity = gravity;

A couple of things about the above code:

  • Since the current user UID is always the same I'm using a constant to make the comparison. You can get the current user UID by using FirebaseAuth.getInstance...
  • To get the padding transformed to DP I'm using a dimen, which you should create at your convenience inside dimens.xml If you have troubles with this you can replace that with a simple number, maybe something like 72.

Finally, I would recommend updating Firebase-ui-database the populateViewHolder is very outdated, current FirebaseRecyclerAdapter is more close to a common RecyvlerView.Adapter regarding method naming and working.

cutiko
  • 9,887
  • 3
  • 45
  • 59
  • I have 2 textviews in a linearlayout so I have to replace all the linearlayout to left/right in the populateViewHolder method – AyoubS Apr 18 '18 at 16:28
  • Do the same what I'm doing for 1 TextView but with 2 TextView, you are using a LinearLayout with vertical orientation so it will be below the message. You can set the same properties I'm setting for 1 TextView to the second TextView. Start solving the problem in a simple manner, make it work with 1 TextView then add the second. – cutiko Apr 18 '18 at 16:37
  • yeap Thank you so much, I did the same but using the RelativeLayout.LayoutParams so now I can change the position of all the linearLayout that contains the message and the sender username and I can align it to the left or right depending on the message sender. – AyoubS Apr 18 '18 at 17:43
0
<androidx.recyclerview.widget.RecyclerView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_above="@+id/linearLayout"
    android:id="@+id/messageRec"
    >
</androidx.recyclerview.widget.RecyclerView>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:layout_alignParentBottom="true"
    android:id="@+id/linearLayout"
    >
    <EditText
        android:layout_width="300dp"
        android:layout_height="wrap_content"
        android:id="@+id/editMessageE"
        />
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="send"
        android:onClick="sendButtonClicked"/>

</LinearLayout>