ConstraintLayout 内的 RecyclerView - 开始位置在 parent 顶部

RecyclerView inside ConstraintLayout - Start position at top of parent

为简单起见,我有一个 ConstraintLayout 和两个孩子:一个 RecyclerView 和一个 Button

我希望 RecyclerView 从 parent 的顶部开始显示。 如果 RecyclerView 中只有几项要显示,则应将它们换行。像这样:

但是,如果 RecyclerView 有足够的项目显示到屏幕末尾,它应该显示到 Button 的顶部,而不是 [=76] 的底部=]. 像这样:

为了达到这个效果我尝试了以下组合:

<android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <Button
            android:id="@+id/my_button"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent" />


        <android.support.v7.widget.RecyclerView
            android:id="@+id/my_recycler_view"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_constrainedHeight="true"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

RecyclerView 只有几个项目要显示时,这个解决方案非常好。否则,如果它必须扩展到屏幕之外,它将位于 Button.

后面

将上面的xml修改为(注意RecyclerView处的app:layout_constraintBottom_toTopOf="@id/my_button"行):

<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/my_button"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent" />


    <android.support.v7.widget.RecyclerView
        android:id="@+id/my_recycler_view"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constrainedHeight="true"
        app:layout_constraintBottom_toTopOf="@id/my_button"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

我得到的结果是:

也就是说,RecyclerView 位于parent 顶部和按钮顶部之间的中心。 如果 RecyclerView 有很多项,这将是可以的,但如果只有少量项,则不行。

问题: 是否可以让我的 RecyclerView 表现得像:

  1. 无论项目数量多少,将其顶部定位在其parent的顶部。

  2. 如果项目少,将内容包裹到最后一项的底部。

  3. 如果有很多项,扩展到Button的顶部,而不是扩展到parent

  4. 的底部

?

P.S。该解决方案应考虑仅使用 parent ConstraintLayout

<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/my_button"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent" />


    <android.support.v7.widget.RecyclerView
        android:id="@+id/my_recycler_view"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toTopOf="@id/my_button"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

您可以使用值为 0app:layout_constraintHorizontal_bias 属性将您的 RecyclerView 与其顶部约束对齐(1 将对齐底部约束)。需要设置顶部和底部约束才能使用此偏差。另一方面,如果未设置底部约束,则无法阻止 RecyclerView 与按钮重叠。这就是设置底部约束并保留 app:layout_constrainedHeight="true" 以确保在其高度设置为 wrap_content.

时强制执行 View's 约束的原因。

您的 RecyclerView 的顶部约束也不正确,因为它的顶部应该包含在父项的顶部而不是底部。

<?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="match_parent">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/my_recycler_view"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_constrainedHeight="true"
            app:layout_constraintVertical_bias="0.0"
            app:layout_constraintBottom_toTopOf="@id/my_button"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <Button
            android:id="@+id/my_button"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>