【问题标题】:two horizontal recycler views side by side if space, or one above the other if not如果有空间,两个水平回收站视图并排,如果没有,则一个在另一个之上
【发布时间】:2021-11-02 17:02:35
【问题描述】:

我有一个 UI 元素,其中包含两个水平回收器视图,每个视图都显示一个图标列表(用作进行选择的切换)。

在大多数情况下,在大多数设备上,将有空间在单行上并排显示两个回收器视图的完整性(即无需滚动)(即 RV2 的开头被限制为 RV1 的结尾) .

但是,如果设备的屏幕特别小,或者在少数情况下每个视图中有超过 4 或 5 个图标,那么将没有足够的空间在一行中完整地显示这些图标,在在这种情况下,我想在自己的行上显示每个回收器视图(即 RV2 的顶部被限制在 RV1 的底部)。

(在非常罕见的情况下,一旦它们在不同的行上,仍然没有足够的空间来显示其中一个 RV 的完整性,那么我可以让 RV 水平滚动!)

基本上,如果只有几个图标,如果它们都在同一行上看起来会更好,但如果没有空间,我宁愿将它们分成两行而不是滚动。

这很容易实现吗?

这是我当前的布局文件,它将 RV 堆叠在一起

<?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"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:descendantFocusability="beforeDescendants"
    android:layout_marginVertical="5dp">

    <de.hdodenhof.circleimageview.CircleImageView
        android:id="@+id/ivPersonImage"
        android:layout_width="64dp"
        android:layout_height="64dp"
        android:layout_marginTop="8dp"
        android:layout_marginBottom="8dp"
        android:background="@drawable/circular_shadow"
        android:src="@drawable/ic_dummy_profile"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <com.myProject.android.custom.InstantAutoComplete
        android:id="@+id/auto_etPersonName"
        style="@style/regular"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginEnd="8dp"
        android:background="@drawable/bg_outline_grey"
        android:gravity="start"
        android:hint="@string/enterNameOrSelectBuddies"
        android:imeOptions="actionDone"
        android:inputType="textEmailAddress|textPersonName"
        android:padding="8dp"
        android:textColor="@color/textColor"
        android:textSize="16sp"
        android:visibility="gone"
        app:layout_constraintBottom_toTopOf="@+id/tvPersonName"

        app:layout_constraintEnd_toStartOf="@+id/ivRemovePerson"
        app:layout_constraintStart_toEndOf="@+id/ivPersonImage"
        app:layout_constraintTop_toTopOf="@id/ivPersonImage" />

    <TextView
        android:id="@+id/tvPersonName"
        style="@style/regular"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:ellipsize="end"
        android:maxLines="1"
        android:paddingHorizontal="8dp"
        android:text="name goes here"
        android:textColor="@color/appThemeColor"
        android:textSize="18sp"
        android:visibility="visible"
        app:layout_constraintBottom_toTopOf="@id/rvSport"
        app:layout_constraintEnd_toStartOf="@+id/ivRemovePerson"
        app:layout_constraintStart_toEndOf="@+id/ivPersonImage"
        app:layout_constraintTop_toBottomOf="@+id/auto_etPersonName" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rvSport"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:orientation="horizontal"
        android:visibility="visible"
        app:layoutManager=".WrapContentLinearLayoutManager"
        app:layout_constraintBottom_toTopOf="@id/rvLevel"
        app:layout_constraintEnd_toStartOf="@+id/ivRemovePerson"
        app:layout_constraintStart_toEndOf="@+id/ivPersonImage"
        app:layout_constraintTop_toBottomOf="@id/tvPersonName"
        app:layout_constraintHorizontal_bias="0"/>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rvLevel"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:orientation="horizontal"
        app:layoutManager=".WrapContentLinearLayoutManager"
        app:layout_constraintBottom_toBottomOf="@id/ivPersonImage"
        app:layout_constraintEnd_toStartOf="@+id/ivRemovePerson"
        app:layout_constraintStart_toEndOf="@+id/ivPersonImage"
        app:layout_constraintTop_toBottomOf="@id/rvSport" />

    <ImageView
        android:id="@+id/ivRemovePerson"
        android:layout_width="24dp"
        android:layout_height="24dp"
        android:layout_marginEnd="16dp"
        android:background="?selectableItemBackgroundBorderless"
        android:src="@drawable/ic_delete_bin_24dp"
        app:layout_constraintBottom_toBottomOf="@id/ivPersonImage"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@id/barrier2"
        app:layout_constraintTop_toTopOf="@id/ivPersonImage" />


    <androidx.constraintlayout.widget.Barrier
        android:id="@+id/barrier2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:barrierDirection="end"
        app:constraint_referenced_ids="auto_etPersonName,tvPersonName"/>
</androidx.constraintlayout.widget.ConstraintLayout>

编辑:

我已经更接近使用流助手来保存两个回收器视图。


    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rvSport"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:orientation="horizontal"
        app:layoutManager=".WrapContentLinearLayoutManager"
        app:layout_constrainedWidth="true"
        tools:itemCount="3"/>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rvLevel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:orientation="horizontal"
        app:layoutManager=".WrapContentLinearLayoutManager"
        app:layout_constrainedWidth="true"
        tools:itemCount="8"/>

    

<androidx.constraintlayout.helper.widget.Flow
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:constraint_referenced_ids="rvSport,rvLevel"
    android:orientation="horizontal"
    app:flow_wrapMode="chain"
    app:layout_constraintStart_toEndOf="@id/ivPersonImage"
    app:layout_constraintEnd_toStartOf="@+id/barrier2"
    app:layout_constraintTop_toBottomOf="@id/tvPersonName"
    app:layout_constraintBottom_toBottomOf="@id/ivPersonImage"
    app:flow_horizontalStyle="packed"
    app:flow_horizontalBias="0"
    app:flow_horizontalGap="10dp"
    app:layout_constrainedWidth="true"
    app:flow_horizontalAlign="start"

    />

当两个 recycler 视图都放在一行上时,此方法有效。 当至少一个回收器视图大于一行时,它可以正常工作(它们显示在单独的行上,回收器视图被剪辑到流的约束中) 当其中一个视图小于其约束时,它不起作用,但两个视图在约束内不适合在同一行上。

例如如果 X 代表约束,Y 是 RV1 内容,Z 是 RV2 内容,我得到这个:

都适合一行 - 在一行上正确显示

XXXXXXXXXXXX
YYY ZZZ

一个更大 - 在单独的行上正确显示(我可以添加任意数量的 Z,它保持在约束范围内,并且 Z 回收器视图水平滚动)

XXXXXXXXXX
年年
ZZZZZZZZZZ

两个 RV 都太大而无法在一行上显示,但对于它自己的行来说都不是太大(即强制水平滚动)。显示不正确,第二个 RV 与其约束重叠。

XXXXXXXXXX
YYY ZZZZZZZZ

app:layout_constrainedWidth="true" 似乎无法与流助手一起正常工作

【问题讨论】:

标签: android android-recyclerview android-constraintlayout


【解决方案1】:

是的,您只需使用两个回收站视图即可轻松实现此目的。您只需要根据您的要求以编程方式更改约束。这是示例:

 ConstraintLayout constraintLayout = findViewById(R.id.parent_layout);
 ConstraintSet constraintSet = new ConstraintSet();
 constraintSet.clone(constraintLayout);
 constraintSet.connect(R.id.imageView,ConstraintSet.RIGHT,R.id.check_answer1,ConstraintSet.RIGHT,0);
 constraintSet.connect(R.id.imageView,ConstraintSet.TOP,R.id.check_answer1,ConstraintSet.TOP,0);
 constraintSet.applyTo(constraintLayout);

【讨论】:

  • 我试图避免采用这种方法,因为它需要手动计算尺寸并决定对布局应用哪些约束。我宁愿让布局做它的事情!
【解决方案2】:

对于其他阅读本文的人,我使用流助手找到了答案。我的一些约束设置不正确,我需要约束流助手,而不是它的内容。

这是现在 100% 按预期工作的完整文件!

<?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"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:tools="http://schemas.android.com/tools"
    android:descendantFocusability="beforeDescendants"
    android:layout_marginVertical="5dp">

    <de.hdodenhof.circleimageview.CircleImageView
        android:id="@+id/ivPersonImage"
        android:layout_width="64dp"
        android:layout_height="64dp"
        android:layout_marginTop="8dp"
        android:layout_marginBottom="8dp"
        android:background="@drawable/circular_shadow"
        android:src="@drawable/ic_dummy_profile"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintEnd_toStartOf="@id/flowSportsLevels"
app:layout_constraintHorizontal_bias="0"        />

    <com.myproject.android.custom.InstantAutoComplete
        android:id="@+id/auto_etPersonName"
        style="@style/regular"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginEnd="8dp"
        android:background="@drawable/bg_outline_grey"
        android:gravity="start"
        android:hint="@string/enterNameOrSelectBuddies"
        android:imeOptions="actionDone"
        android:inputType="textEmailAddress|textPersonName"
        android:padding="8dp"
        android:textColor="@color/textColor"
        android:textSize="16sp"
        android:visibility="gone"
        app:layout_constraintBottom_toTopOf="@+id/tvPersonName"

        app:layout_constraintEnd_toStartOf="@+id/ivRemovePerson"
        app:layout_constraintStart_toEndOf="@+id/ivPersonImage"
        app:layout_constraintTop_toTopOf="@id/ivPersonImage" />

    <TextView
        android:id="@+id/tvPersonName"
        style="@style/regular"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:ellipsize="end"
        android:maxLines="1"
        android:paddingHorizontal="8dp"
        tools:text="name here"
        android:textColor="@color/appThemeColor"
        android:textSize="18sp"
        android:visibility="visible"
        app:layout_constraintBottom_toTopOf="@id/flowSportsLevels"
        app:layout_constraintEnd_toStartOf="@+id/ivRemovePerson"
        app:layout_constraintStart_toEndOf="@+id/ivPersonImage"
        app:layout_constraintTop_toBottomOf="@+id/auto_etPersonName" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rvSport"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:orientation="horizontal"
        app:layoutManager=".WrapContentLinearLayoutManager"
        app:layout_constrainedWidth="true"
        tools:itemCount="3"/>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rvLevel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:orientation="horizontal"
        app:layoutManager=".WrapContentLinearLayoutManager"
        app:layout_constrainedWidth="true"
        tools:itemCount="4"/>



<androidx.constraintlayout.helper.widget.Flow
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:constraint_referenced_ids="rvSport,rvLevel"
    android:orientation="horizontal"
    app:flow_wrapMode="chain"
    app:layout_constraintStart_toEndOf="@id/ivPersonImage"
    app:layout_constraintEnd_toStartOf="@+id/barrier2"
    app:layout_constraintTop_toBottomOf="@id/tvPersonName"
    app:layout_constraintBottom_toBottomOf="@id/ivPersonImage"
    app:flow_horizontalStyle="packed"
    app:flow_horizontalBias="0"
    app:flow_horizontalGap="10dp"
    app:layout_constrainedWidth="true"
    app:flow_horizontalAlign="start"
    android:id="@+id/flowSportsLevels"
    android:layout_marginHorizontal="10dp"
    />

    <ImageView
    android:id="@+id/ivRemovePerson"
    android:layout_width="24dp"
    android:layout_height="24dp"
    android:layout_marginEnd="16dp"
    android:background="?selectableItemBackgroundBorderless"
    android:src="@drawable/ic_delete_bin_24dp"
    app:layout_constraintBottom_toBottomOf="@id/ivPersonImage"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toEndOf="@id/barrier2"
    app:layout_constraintTop_toTopOf="@id/ivPersonImage" />
    <androidx.constraintlayout.widget.Barrier
        android:id="@+id/barrier2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:barrierDirection="end"
        app:constraint_referenced_ids="auto_etPersonName,tvPersonName"/>
   
</androidx.constraintlayout.widget.ConstraintLayout>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-10
    • 1970-01-01
    • 2023-03-25
    • 2011-05-03
    • 2019-12-09
    • 1970-01-01
    • 2019-05-19
    • 2023-02-22
    相关资源
    最近更新 更多