【问题标题】:ConstraintLayout with Barriers; How to constraint to bottom / top of barrier depending on size带障碍的约束布局;如何根据大小限制到屏障的底部/顶部
【发布时间】:2017-05-28 22:11:02
【问题描述】:

我正在尝试 1.1.0-beta1 中的新屏障功能。它按预期工作,但是我似乎无法理解这个用例或(或者可能是 ConstraintLayout?)

我想要完成的是:我在左侧有一个 imageview,在 imageview 的右侧有一个标题和副标题文本视图。 Imageview 是固定高度。我有一个按钮,它的底部被限制在 imageview 的底部

(顺便说一句,我也尝试将其底部约束到 imageview 的底部,并将顶部约束到 textview 的底部,并使其向底部倾斜 1.0,但不适用于大文本大小写)

使用障碍物,我只能将按钮顶部限制在障碍物底部(或顶部,似乎相同)

<?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"
   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"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@color/blue"/>

    <ImageView
        android:id="@+id/imageView4"
        android:layout_width="0dp"
        android:layout_height="150dp"
        android:layout_marginLeft="0dp"
        android:layout_marginRight="0dp"
        android:layout_marginTop="0dp"
        android:scaleType="centerCrop"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/books"/>

    <ImageView
        android:id="@+id/imageView6"
        android:layout_width="124dp"
        android:layout_height="156dp"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="8dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/imageView4"
        app:srcCompat="@android:drawable/radiobutton_on_background"/>

    <TextView
        android:id="@+id/textView4"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        android:layout_marginTop="8dp"
        android:text="TextView"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintLeft_toRightOf="@+id/imageView6"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/imageView4"/>

    <TextView
        android:id="@+id/textView5"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="Lorem Ipsum je fiktívny text, používaný pri návrhu tlačovín a typografie. Lorem Ipsum je štandardným výplňovým textom už od 16. storočia, keď neznámy tlačiar zobral sadzobnicu plnú tlačových znakov a pomiešal ich, aby tak vytvoril vzorkovú knihu. Prežil nielen päť storočí, ale aj skok do elektronickej sadzby, a pritom zostal v podstate nezmenený. Spopularizovaný bol v 60-tych rokoch 20.storočia, vydaním hárkov Letraset, ktoré obsahovali pasáže Lorem Ipsum, a neskôr aj publikačným softvérom"
        app:layout_constraintLeft_toLeftOf="@+id/textView4"
        app:layout_constraintRight_toRightOf="@+id/textView4"
        app:layout_constraintTop_toBottomOf="@+id/textView4"/>

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintTop_toBottomOf="@+id/textView5"
        app:layout_constraintRight_toRightOf="parent"/>

</android.support.constraint.ConstraintLayout>

图像中的两种状态:

【问题讨论】:

  • 请用您尝试过的 xml 更新您的问题。
  • 这是我描述的微不足道的例子,但无论如何添加它

标签: android viewgroup android-constraintlayout


【解决方案1】:

这是一个适合您的布局。它有点复杂,但可以满足您的需求。以下是它的工作原理和设置方式:

  • 定义一个不可见按钮blockingButton,它与您的其他按钮具有相同的尺寸。将此按钮限制在左下方ImageView

  • blockingButton 之上,放置一个Space 小部件。这个Space 小部件的位置将定义底部按钮将浮动到的最大高度。

  • 定义一个浮动在Space 小部件和大TextView 下方的屏障。

  • 最后,将浮动按钮的顶部限制在屏障上。

随着大TextView 中文本大小的变化,按钮将向上浮动至Space 小部件,但不会更远。随着TextView 的增长,它将按下屏障和底部按钮。

这是short video

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

    <ImageView
        android:id="@+id/imageView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@color/blue" />

    <ImageView
        android:id="@+id/imageView4"
        android:layout_width="0dp"
        android:layout_height="150dp"
        android:scaleType="centerCrop"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/books" />

    <ImageView
        android:id="@+id/imageView6"
        android:layout_width="124dp"
        android:layout_height="156dp"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="8dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/imageView4"
        app:srcCompat="@android:drawable/radiobutton_on_background"
        android:layout_marginStart="8dp" />

    <TextView
        android:id="@+id/textView4"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginEnd="16dp"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        android:layout_marginStart="16dp"
        android:layout_marginTop="8dp"
        android:text="TextView"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintLeft_toRightOf="@+id/imageView6"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/imageView4" />

    <TextView
        android:id="@+id/textView5"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="17dp"
        android:text="Lorem Ipsum je fiktívny text, používaný pri návrhu tlačovín a typografie. Lorem Ipsum je štandardným výplňovým textom už od 16. storočia, keď neznámy tlačiar zobral sadzobnicu plnú tlačových znakov a pomiešal ich, aby tak vytvoril vzorkovú knihu. Prežil nielen päť storočí, ale aj skok do elektronickej sadzby, a pritom zostal v podstate nezmenený. Spopularizovaný bol v 60-tych rokoch 20.storočia, vydaním hárkov Letraset, ktoré obsahovali pasáže Lorem Ipsum, a neskôr aj publikačným softvérom"
        app:layout_constraintLeft_toLeftOf="@+id/textView4"
        app:layout_constraintRight_toRightOf="@+id/textView4"
        app:layout_constraintTop_toBottomOf="@+id/textView4"
        app:layout_constraintHorizontal_bias="0.0" />

<!-- This is the start of the changes. -->
    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/barrier" />

    <Button
        android:id="@+id/blockingButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        android:visibility="invisible"
        app:layout_constraintBottom_toBottomOf="@+id/imageView6"
        app:layout_constraintLeft_toLeftOf="@+id/imageView6" />

    <android.support.v4.widget.Space
        android:id="@+id/spacer"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintBottom_toTopOf="@+id/blockingButton" />

    <android.support.constraint.Barrier
        android:id="@+id/barrier"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:barrierDirection="bottom"
        app:constraint_referenced_ids="spacer, textView5" />

</android.support.constraint.ConstraintLayout>

【讨论】:

  • 甜蜜的技术,现在想想你甚至可以为假按钮留出空间
  • @urSus 是的。我使用了一个与浮动按钮具有相同特性的按钮来获得正确的高度。您将了解更多有关要求和大小的信息,因此假按钮的Space 可能就是问题所在。很高兴您发现这很有帮助。
  • 如何以编程方式创建此屏障?
【解决方案2】:

@Cheticamp 的回答很好,但他没有解释他是如何提出这个想法的。

这是我受他的解决方案启发而提出另一个解决方案的方法。

我们想要实现的是将按钮放得尽可能高,但应该限制在两个限制内:

  1. button.bottom >= image.bottom

  2. button.top >= text.bottom

我们可以使用Barrier来满足这两个要求,但是我们需要修改其中一个,我选择修改第二个:

button.top >= text.bottom button.bottom >= text.bottom + button.height

现在我们有这两个约束:

  1. button.bottom >= image.bottom

  2. button.bottom >= text.bottom + button.height

现在我们可以像这样在TextView 下方放置一个假按钮:

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <ImageView
        android:id="@+id/imageView"
        android:layout_width="124dp"
        android:layout_height="156dp"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="8dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@android:drawable/radiobutton_on_background"/>

    <TextView
        android:id="@+id/textView1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        android:layout_marginTop="8dp"
        android:text="TextView"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintLeft_toRightOf="@+id/imageView"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <TextView
        android:id="@+id/textView2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="Lorem Ipsum je fiktívny text, používaný pri návrhu tlačovín a typografie. Lorem Ipsum je štandardným výplňovým textom už od 16. storočia, keď neznámy tlačiar zobral sadzobnicu plnú tlačových znakov a pomiešal ich, aby tak vytvoril vzorkovú knihu. Prežil nielen päť storočí, ale aj skok do elektronickej sadzby, a pritom zostal v podstate nezmenený. Spopularizovaný bol v 60-tych rokoch 20.storočia, vydaním hárkov Letraset, ktoré obsahovali pasáže Lorem Ipsum, a neskôr aj publikačným softvérom"
        app:layout_constraintLeft_toLeftOf="@+id/textView1"
        app:layout_constraintRight_toRightOf="@+id/textView1"
        app:layout_constraintTop_toBottomOf="@+id/textView1"/>

    <Button
        android:id="@+id/button_fake"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        android:visibility="invisible"
        app:layout_constraintTop_toBottomOf="@+id/textView2"
        app:layout_constraintRight_toRightOf="parent"/>

    <android.support.constraint.Barrier
        android:id="@+id/barrier"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:barrierDirection="bottom"
        app:constraint_referenced_ids="imageView,button_fake"
        />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintBottom_toBottomOf="@+id/barrier"
        app:layout_constraintRight_toRightOf="parent"/>

</android.support.constraint.ConstraintLayout>

【讨论】:

    猜你喜欢
    • 2023-01-28
    • 2018-08-01
    • 2019-05-06
    • 1970-01-01
    • 2017-10-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-19
    • 1970-01-01
    相关资源
    最近更新 更多