【问题标题】:RecylerView item's maxWidth changes due to lots of elementsRecyclerView items max 宽度因大量元素而变化
【发布时间】:2021-08-02 02:46:37
【问题描述】:

所以我正在构建一个聊天应用程序。我使用RecyclerView来显示消息,并将消息列表项的maxWidth设置为设备宽度的75%,在布局中,宽度为ConstraintLayout中的0dp,使其具有动态性。这使得它对于较小的文本更加简洁,当它是一个更长的文本时,它只是在达到 maxWidth 后将其发送到下一行。在项目列表增加之前,一切都运行良好。当有很多数据时,RecyclerView 使宽度像上一个列表项一样(我知道RecyclerView 回收视图)。对此的一种解决方案是在AdapterViewHolder 中添加setIsRecyclable(false);。这确实有效,但列表项相互重叠,或者当一个列表项的数据发生更改时,它会重叠自身,在自身上创建另一项作为更改项。由于它不会回收视图,因此它会在列表项发生任何更改后自行创建新视图。我不知道该怎么办。我应该求助于ListView 吗?或者有没有其他解决方案?为了上下文,这是我的代码。

ViewHolder 设置maxWidth

public ChatViewHolder(@NonNull @NotNull View itemView, int width) {
    super(itemView);
    ...
    ...
   
    sendContainer.setMaxWidth(width);
    comeContainer.setMaxWidth(width);
}

onCreateViewHolder计算maxWidth

    @Override
    public ChatViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.message_list_item, parent, false);
        int width = (int) (parent.getWidth() * 0.75);
        return new ChatViewHolder(view, width);
    }

【问题讨论】:

    标签: java android android-recyclerview


    【解决方案1】:

    我认为您实际上不需要在代码本身中做任何事情。约束布局本身就有能力实现这一点。这是我曾经使用过的聊天设计示例。

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimaryBackground">
    
        <TextView
            android:id="@+id/tvMsgSelf"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:layout_marginEnd="24dp"
            android:background="@drawable/drawable_chat_self"
            android:paddingStart="12dp"
            android:paddingTop="16dp"
            android:paddingEnd="12dp"
            android:paddingBottom="16dp"
            android:textSize="14sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="1"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintWidth_max="wrap"
            app:layout_constraintWidth_percent="0.72"
            tools:text="dgdgdgdgdfddg dfgdf gdf gdf gdf gdf gdfd g dg dfg dfg df gd gdf gdf g dfg dfg dfg dfg df g dfg df g dfgdfg" />
    
        <TextView
            android:id="@+id/tvTimeStampSelf"
            style="@style/StyleRegular"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="4dp"
            android:textColor="@color/colorSecondaryText"
            android:textSize="12sp"
            app:layout_constraintEnd_toEndOf="@+id/tvMsgSelf"
            app:layout_constraintTop_toBottomOf="@+id/tvMsgSelf"
            tools:text="2 Jan,20, 10:50PM" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    这里的主要属性是app:layout_constraintWidth_percent="0.72"app:layout_constraintWidth_max="wrap"。这将它的宽度限制为从那里开始的任何给定屏幕的 72%。

    【讨论】:

    • 我真的明白了。我说它确实有效。但是RecyclerView 会回收视图。因此,当列表项很多时,宽度有时会变为全部的 75%,而不是自动换行。事实上,当您重新启动应用程序时。它再次完美地展示了一切。
    • 它回收并使用前一个项目的宽度,即完整的 75%,并使用该宽度使更小的文本变为 75% 宽度
    • 我不知道该知道什么\
    • 我是说你甚至不需要为这一切而烦恼。只需按照我上面提到的方式设计布局,它就会自动调整到屏幕的 75%。您根本不需要在 ViewHolder 中进行任何更改。您可以在约束布局本身中调整它@SimranSharma
    • 我做到了。但是由于它会回收视图,因此当您滚动时会快速更改宽度。当您重新启动时,一切都会恢复完美,就像我想要的那样,但在滚动后它的宽度再次发生变化
    猜你喜欢
    • 2015-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-16
    • 1970-01-01
    • 2016-08-16
    • 2015-01-21
    • 2015-03-24
    相关资源
    最近更新 更多