约束布局:不能分离元素并将它们全部显示在屏幕上

Constraint layout: Cannot separate elements and keep them all on screen

我有一个像这样的简单约束布局:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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="match_parent"
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/main_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@id/rescan"
        />

    <android.support.v7.widget.AppCompatButton
        android:id="@+id/rescan"
        android:layout_width="wrap_content"
        android:text="@string/rescan_button"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintBottom_toBottomOf="parent"
        />

</android.support.constraint.ConstraintLayout>

尽管 layout_constraintBottom_toTopOf="@id/rescan",列表视图可能会延伸到按钮的一半。

为了尝试纠正这个问题,我添加了硬编码维度(我不想这样做);到列表视图:

android:layout_marginBottom="50sp"

以及按钮:

android:layout_height="40sp"
android:textSize="20sp"
android:layout_margin="10sp"

然而,我得到了这个(模拟器图片,设计视图也对应于此):

按钮在屏幕中间。

所以我决定删除硬编码维度并使用 屏障。 developer page 对于 barrierDirection 的工作方式含糊不清,但是 这个 "constraintlayout.com" 示例 清楚地表明方向应该是相对于 referenced_ids 中列出的元素而言您希望设置障碍的一侧。基于此,这是我在约束布局中的内容:

<ListView
    android:id="@+id/main_list"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintBottom_toTopOf="@id/bottomBarrier"
    />

<android.support.constraint.Barrier
    android:id="@+id/bottomBarrier"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:barrierDirection="top"
    app:constraint_referenced_ids="@id/rescan"
    />

<android.support.v7.widget.AppCompatButton
    android:id="@+id/rescan"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/rescan_button"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintHorizontal_bias="0.5"
    />     

但情况并没有真正好转...

说不清,但这里的结界在最底下。这就解释了为什么带有 Bottom_toTopOf 屏障的列表视图现在也一直延伸到底部。

然而,这让整个障碍,谁的方向是top,谁的id是按钮,完全没有意义。绝不是将列表视图保持在一侧,将按钮保持在另一侧。都在他们下面。

更狂暴:如果我将方向更改为 bottom 并保留其他所有内容,屏障会跳到最顶部,列表视图会向上跳到屏幕的一半,按钮会留在原位.

我完全糊涂了。我最大的两个问题是:

  1. 为什么在第一张图片中,当按钮设置为从下到上时,列表视图会延伸到按钮的一半?

  2. 为什么最后一张图是屏障,方向"top",引用了按钮id,按钮下方

1。 您的 ListView's 高度设置为 wrap_content,这意味着视图将计算自己的大小并且约束不会限制尺寸。 ConstraintLayout-1.1.0 引入了允许使用 wrap_content 的新属性,但仍继续强制执行约束以限制指定的维度。这些属性是:

app:layout_constrainedWidth="true"
app:layout_constrainedHeight="true"

2。 至于 Barrier,您引用视图 ID 的方式有误:

app:constraint_referenced_ids="@id/rescan"

这应该改为:

app:constraint_referenced_ids="rescan"