ConstraintLayout with Barriers; How to constraint to bottom / top of barrier depending on size

一笑奈何 提交于 2019-12-01 00:59:52

Here is a layout that will work for you. It is a little complicated but does what you want. Here is how it works and is set up:

  • Define an invisible button, blockingButton, that has the same dimensions as your other button. Constrain this button to the bottom of your left ImageView.

  • On top of blockingButton, place a Space widget. The location of this Space widget will define the maximum height that the bottom button will float to.

  • Define a barrier that floats below the Space widget and the large TextView.

  • Finally, constrain the top of your floating button to the barrier.

As the size of the text changes in the large TextView, the button will float up as far as the Space widget but no farther. As the TextView grows, it will push down the barrier and the bottom button.

Here is a 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>
ssynhtn

@Cheticamp 's answer is great, but he doesn't explain how he came up that idea.

Here is how I came up another solution inspired by his solution.

What we want to achieve is to put the button as high as possible, but it should be constrained to two limits:

  1. button.bottom >= image.bottom

  2. button.top >= text.bottom

We can use Barrier to satisfy these two requirements, but we need to modify one of them, I choose to modify the second one:

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

Now we have these two constraints:

  1. button.bottom >= image.bottom

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

Now we can place a fake button below the TextView like this:

<?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>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!