ConstrainLayout:如何将视图的顶部约束到高度最大的视图的底部?

3

我正在尝试在我们的项目中使用ConstraintLayout

我想实现的布局可以简化为以下内容:

布局顶部有两个视图(称为TopA和TopB),下方有另一个视图(称为BottomC)。

TopB的高度可变,在不同情况下,TopB的高度可能大于或小于TopA的高度。

我的问题是:如何将BottomC约束到具有较大高度的顶部视图的底部,以便BottomC不会被具有较大高度的视图覆盖。(如下所示的屏幕截图)

我可以通过将TopA和TopB添加到额外的ViewGroup(例如LinearLayout)中,并将BottomC约束到该ViewGroup的底部来实现这一点。但是否可能在不引入额外的ViewGroup的情况下实现呢?

enter image description here enter image description here


你的进度条看起来是临时的,这意味着它在加载或其他操作时会被启用。如果是这种情况,请将其声明在topViews下方/后方,因为在ConstraintLayout中,与其他布局不同,最后声明的小部件将保持在顶部。这样,当进度条启用时,它将始终保持在顶部,不受topView大小的影响。 - Lalit Fauzdar
@LalitSinghFauzdar 这些屏幕截图只是为了让我的问题更加清晰明了。ProgressBar可以是任何类型的视图。非常感谢您提供的出色建议。 - Jiaqi Liu
3个回答

11

发布问题3分钟后,我发现最近发布的1.1.x版本的ConstrainLayout具有一项名为Barrier的新功能,并且ConstrainLayout的官方培训文档已经更新,介绍了该功能

这正是我在寻找的。希望这可以帮助像我这样的人。

实际布局代码看起来像这样(请注意android.support.constraint.Barrier节点):

<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" >

    <ImageView
        android:id="@+id/topA"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@mipmap/ic_launcher"/>

    <TextView
        android:id="@+id/topB"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="24dp"
        android:text="Text"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.75"
        app:layout_constraintStart_toEndOf="@+id/topA"
        app:layout_constraintTop_toTopOf="@+id/topA"
        />

    <android.support.constraint.Barrier
        android:id="@+id/barrier4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:barrierDirection="bottom"
        app:constraint_referenced_ids="topA,topB"
        tools:layout_editor_absoluteY="16dp"/>

    <ProgressBar
        android:id="@+id/progressBar"
        style="?android:attr/progressBarStyle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.50"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/barrier4"/>

</android.support.constraint.ConstraintLayout>

啊!那就是我忘记的名字。这对他来说将是一个很大的帮助。 - Lalit Fauzdar

1
实际上,这是ConstraintLayout常见的问题,基本上有两个选项。一种是如果您的ImageView高度固定,则将TextView最小高度设置为ImageView的高度;另一种是现在引入了Barrier,但这是Beta版本,如果要在Beta版本中使用,请按以下设置进行设置。
这是ConstraintLayout中引入的新功能,目前处于Beta版本。
如何将beta ConstraintLayout添加到项目中,请按照以下步骤进行设置。
在项目gradle文件中添加maven支持,如下所示。
allprojects {
    repositories {
        maven { url 'https://maven.google.com' }
        jcenter()
    }
}

然后在应用程序的gradle依赖项中添加ConstraintLayout库依赖

compile 'com.android.support.constraint:constraint-layout:1.1.0-beta3'

在布局中添加障碍。
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <ImageView
        android:id="@+id/imageView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@mipmap/ic_launcher" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:text="TextView"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/imageView2"
        app:layout_constraintTop_toTopOf="parent" />

    <android.support.constraint.Barrier
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:id="@+id/barrier1"
        app:barrierDirection="bottom"
        app:constraint_referenced_ids="textView2, imageView2"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView2" />

    <TextView
        android:id="@+id/textView3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:text="TextView"
        app:layout_constraintTop_toBottomOf="@id/barrier1"
        app:layout_constraintStart_toStartOf="parent" />
</android.support.constraint.ConstraintLayout>

Beta3现已发布,修复了一些问题并增加了新功能 https://androidstudio.googleblog.com/2017/10/constraintlayout-110-beta-3-is-now.html


0

选项1: 我建议通过将两个视图(图片、文本视图)添加到一个视图组(任何都可以)然后将进度条约束到视图组的底部来完成以下操作。(编辑:刚刚看到你说不要视图组,所以选项2)

选项2: 但是,如果您必须以编程方式进行动画或其他原因,我建议阅读以下内容:

https://developer.android.com/reference/android/support/constraint/ConstraintSet.html

并且

https://developer.android.com/reference/android/transition/TransitionManager.html


谢谢您的回复。我刚刚发现谷歌在1.1.x版本中为ConstrainLayout添加了一个名为“Barrier”的新功能,这解决了我的问题。 - Jiaqi Liu
2
实际上,在ConstraintLayout中嵌套视图是不被鼓励的。ConstraintLayout的主要目标是扁平化布局。了解更多关于ConstraintLayout性能优势的内容,请阅读Understanding the performance benefits of ConstraintLayout - Eugene Brusov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接