首页 > 解决方案 > 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);
        }
    }

}

注意:我注意到当消息离开屏幕并且您向上滚动时布局会发生变化。

标签: android

解决方案


您需要更改您的 onCreateViewHolder,在 else 中保留以下行

    view = layoutInflater.inflate(R.layout.other_text_message,parent,false);
    return new TextChatRecieverViewHolder(view);

还要保持布局宽度

wrap_content 

而不是

match_parent.
        

推荐阅读