android - RecyclerView 中的布局行为怪异
问题描述
我正在尝试在 RecyclerView 中实现聊天应用类型布局。现在唯一的问题是,即使我已将 View 的宽度设置为环绕文本。在 RecyclerView 内,有时小词占据整行,有时单词很好。
绿色突出显示是预期行为,红色是意外行为。
这是cardView的代码
<androidx.cardview.widget.CardView
android:id="@+id/cardView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
app:cardBackgroundColor="#00BCD4"
app:cardCornerRadius="12dp"
app:cardPreventCornerOverlap="false"
app:cardUseCompatPadding="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.123">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textMessageSent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxWidth="260dp"
android:paddingBottom="8dp"
android:paddingLeft="12dp"
android:paddingRight="12dp"
android:paddingTop="8dp"
android:text="oh noo"
android:textColor="#000000"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:maxLines="10" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
这是适配器代码
public class ChatAdapter extends ListAdapter {
String reciever,sender;
public ChatAdapter(String from,String to)
{
super(DIFF_CALLBACK);
this.reciever = from;
this.sender = to;
}
private static final DiffUtil.ItemCallback<Chat> DIFF_CALLBACK = new DiffUtil.ItemCallback<Chat>() {
@Override
public boolean areItemsTheSame(@NonNull Chat oldItem, @NonNull Chat newItem) {
return oldItem.getId() == newItem.getId();
}
@Override
public boolean areContentsTheSame(@NonNull Chat oldItem, @NonNull Chat newItem) {
return oldItem.getSender().equals(newItem.getSender()) &&
oldItem.getReciever().equals(newItem.getReciever()) &&
oldItem.getDate().equals(newItem.getDate()) &&
oldItem.getMessageIdSent() == newItem.getMessageIdSent() &&
oldItem.getMessageRecieved().equals(newItem.getMessageRecieved()) &&
oldItem.getTime().equals(newItem.getTime());
}
};
private final int TEXT_MESSAGE_SENT = 0;
private final int TEXT_MESSAGE_RECIEVED = 1;
@Override
public int getItemViewType(int position) {
Chat currentChats = (Chat) getItem(position);
if(!currentChats.getMessageRecieved().equals(""))
{
return TEXT_MESSAGE_RECIEVED;
}
else if(!currentChats.getMessageSent().equals(""))
{
return TEXT_MESSAGE_SENT;
}
return -1;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view;
if(viewType == TEXT_MESSAGE_SENT)
{
view = layoutInflater.inflate(R.layout.me_text_message,parent,false);
return new TextChatSenderViewHolder(view);
}
//if reciever is text
view = layoutInflater.inflate(R.layout.other_text_message,parent,false);
return new TextChatRecieverViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
Chat currentChat = (Chat) getItem(position);
switch (holder.getItemViewType())
{
case TEXT_MESSAGE_RECIEVED:
//bind REcievedText viewholder
TextChatRecieverViewHolder viewHolder = (TextChatRecieverViewHolder) holder;
if(!currentChat.getMessageRecieved().equals(""))
{
viewHolder.textMessageRecieved.setText(currentChat.getMessageRecieved());
viewHolder.textTimeMessageRecieved.setText(currentChat.getTime());
}
break;
case TEXT_MESSAGE_SENT:
TextChatSenderViewHolder viewHolder2 = (TextChatSenderViewHolder) holder;
if(!currentChat.getMessageSent().equals("")) {
viewHolder2.textMessageSent.setText(currentChat.getMessageSent());
viewHolder2.textTimeMessageSent.setText(currentChat.getTime());
}
break;
}
}
class TextChatSenderViewHolder extends RecyclerView.ViewHolder
{
TextView textMessageSent,textTimeMessageSent;
public TextChatSenderViewHolder(@NonNull View itemView) {
super(itemView);
textTimeMessageSent = itemView.findViewById(R.id.textTimeMessageSent);
textMessageSent = itemView.findViewById(R.id.textMessageSent);
}
}
class TextChatRecieverViewHolder extends RecyclerView.ViewHolder
{
TextView textMessageRecieved,textTimeMessageRecieved;
public TextChatRecieverViewHolder(@NonNull View itemView) {
super(itemView);
textTimeMessageRecieved = itemView.findViewById(R.id.textTimeMessageRecieved);
textMessageRecieved = itemView.findViewById(R.id.textMessageRecieved);
}
}
}
注意:我注意到当消息离开屏幕并且您向上滚动时布局会发生变化。
解决方案
您需要更改您的 onCreateViewHolder,在 else 中保留以下行
view = layoutInflater.inflate(R.layout.other_text_message,parent,false);
return new TextChatRecieverViewHolder(view);
还要保持布局宽度
wrap_content
而不是
match_parent.
推荐阅读
- javascript - 将 null 替换为空字符串(RestAPI 对象)
- android - 从活动中获得结果的非陈旧方式?
- flutter - Flutter Firebase 消息传递:在收到后台通知时打开一个新屏幕
- javascript - 小计函数计算仅在第二次单击时起作用
- r - 基于序列其余部分的具有给定属性的元素的索引
- nginx - 如何在启用安全链接模块的情况下使 Nginx 作为 WebSocket 代理工作
- redux-toolkit - Redux-toolkit createEntityAdapter
- angular - 如何通过将 jwt 传递到 cookie 中的前端来编程 auth-guards?
- android - 在执行获取请求时使用改造 2 我收到 404 错误,但如果使用邮递员,api 会给出响应
- python - 颤动矢量箭头未与 pcolormesh 中的原始网格点对齐