我正在使用Firebase开发聊天应用程序。 为了显示消息,我正在使用recyclerView和FirebaseRecyclerAdapter。 问题是我想根据消息的发送者更改与此FirebaseRecyclerAdapter关联的布局,以便发送方和接收方的消息看起来不同,但我不知道如何做到这一点。
如果您有任何想法,请告诉我! 这些是我的onStart方法和viewHolder类以及消息的布局。
谢谢大家。
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);
}
}
这是我的第一个消息布局,称为"单消息布局.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>
这是我的第二个消息布局,称为"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>
如果您查看消息传递应用程序,您会注意到通过将收到的消息放在左侧并将发送消息放在右侧来提供可用性。 这意味着您需要知道消息是否来自当前用户,因此您的模型应该有一个标识符。UID或电子邮件应该这样做。像这样:
{
"message": "hello world",
"sender": UID1
}
为了简化问题,我的解决方案是使用单个布局,然后根据标识符以编程方式更改布局的属性,如果与当前用户匹配,则它将向右移动,如果不是收到的消息,它将转到左侧。
<?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>
我使用LinearLayout
作为容器,因为发现更容易设置填充和重力,但您可以使用其他东西。
下一个代码块应该进入你的populateViewHolder
方法中
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;
关于上述代码的几件事:
- 由于当前用户 UID 始终相同,因此我使用常量进行比较。可以使用
FirebaseAuth.getInstance...
获取当前用户 UID - 为了使填充转换为DP,我正在使用一个
dimen
,您应该在方便时在dimens.xml
中创建它 如果您对此有问题,可以用一个简单的数字代替它,也许是像72
.
最后,我建议更新Firebase-ui-database,populateViewHolder
非常过时,当前FirebaseRecyclerAdapter
更接近于方法命名和工作的常见RecyvlerView.Adapter
。
<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>