0

I want to build the following layout using ConstraintLayout:

Mockup

I use this source for layout:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:background="@color/colorAccent">

        <ImageView
            android:id="@+id/imageView"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:scaleType="centerCrop"
            app:srcCompat="@android:color/darker_gray"
            app:layout_constraintDimensionRatio="h,16:9"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintBottom_toTopOf="@+id/textView1" />

        <TextView
            android:id="@+id/textView1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="24dp"
            android:layout_marginLeft="16dp"
            android:layout_marginRight="16dp"
            android:text="Title"
            android:textAppearance="@style/TextAppearance.AppCompat.Headline"
            app:layout_constraintTop_toBottomOf="@+id/imageView"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintBottom_toTopOf="@+id/textView2" />

        <TextView
            android:id="@+id/textView2"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:layout_marginLeft="16dp"
            android:layout_marginRight="16dp"
            android:layout_marginBottom="24dp"
            android:text="Subtle"
            app:layout_constraintTop_toBottomOf="@+id/textView1"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintBottom_toBottomOf="parent" />

    </android.support.constraint.ConstraintLayout>
</FrameLayout>

And unfortunately get this result:

Result view

As you can see there's an unnecessary margin on the top of ImageView, though layout indicates marginTop=0.

Eugene Brusov
  • 17,146
  • 6
  • 52
  • 68
  • Your layout_gravity is center. Remove that and you should be good to go – NSimon Oct 05 '17 at 14:46
  • @NSimon No, it doesn't help... See this screenshot https://www.dropbox.com/s/rftoxtk76jg3r6i/Screenshot_1507214820.png?dl=0 – Eugene Brusov Oct 05 '17 at 14:51
  • Remove this: app:layout_constraintBottom_toTopOf="@+id/textView1" – Suhayl SH Oct 05 '17 at 15:00
  • @SuhaylSH If `app:layout_constraintBottom_toTopOf="@+id/textView1"` removed then somehow I get 40dp vertical distance between textView1 and imageView. See this screenshot https://www.dropbox.com/s/tjw1raf224aaq6l/device-2017-10-05-185647%20copy.png?dl=0 – Eugene Brusov Oct 05 '17 at 17:02

5 Answers5

1

I need to get rid of this top margin

For this,just Remove this line

app:layout_constraintBottom_toTopOf="@+id/textView1"

from your ImageView

Anurag
  • 1,162
  • 6
  • 20
  • See results https://www.dropbox.com/s/tjw1raf224aaq6l/device-2017-10-05-185647%20copy.png?dl=0. Now vertical distance between textView1 and imageView is about 40dp. – Eugene Brusov Oct 05 '17 at 17:03
1

The first two answer will work. You can also add app:layout_constraintVertical_chainStyle="spread_inside" to the top ImageView if you want to maintain your vertical chain.

Here is an image after adding this statement (but not changing anything else.)

enter image description here

Here is the XML:

<FrameLayout 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.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:background="@color/colorAccent">

        <ImageView
            android:id="@+id/imageView"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:scaleType="centerCrop"
            app:srcCompat="@android:color/darker_gray"
            app:layout_constraintDimensionRatio="h,16:9"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintVertical_chainStyle="spread_inside"
            app:layout_constraintBottom_toTopOf="@+id/textView1" />

        <TextView
            android:id="@+id/textView1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="24dp"
            android:layout_marginLeft="16dp"
            android:layout_marginRight="16dp"
            android:text="Title"
            android:textAppearance="@style/TextAppearance.AppCompat.Headline"
            app:layout_constraintTop_toBottomOf="@+id/imageView"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintBottom_toTopOf="@+id/textView2" />

        <TextView
            android:id="@+id/textView2"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:layout_marginLeft="16dp"
            android:layout_marginRight="16dp"
            android:layout_marginBottom="24dp"
            android:text="Subtle"
            app:layout_constraintTop_toBottomOf="@+id/textView1"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintBottom_toBottomOf="parent" />

    </android.support.constraint.ConstraintLayout>
</FrameLayout>

Update: So the above doesn't work on API 23 with ConstraintLayout version 1.0.2. Try the following instead:

Remove android:layout_marginTop="16dp" from textView2 and add android:layout_marginBottom="16dp" to textView1. This makes a difference.

Cheticamp
  • 61,413
  • 10
  • 78
  • 131
  • The first two answer don't work, I get around 40dp distance between textView1 and imageView https://www.dropbox.com/s/tjw1raf224aaq6l/device-2017-10-05-185647%20copy.png?dl=0. With "spread_inside" I got no vertical margin between textView1 and textView2. See this screenshot https://www.dropbox.com/s/59nixtlhnah44j7/device-2017-10-05-190906.png?dl=0. – Eugene Brusov Oct 05 '17 at 17:10
  • Just copied/pasted your source code and get these results on Nexus 5 simulator running on API 23 and the same results on real Nexus 5 running on API 23 https://www.dropbox.com/s/x48wk7sgk4ma6d5/Screenshot_1507223903.png?dl=0. As you can see now there's no space between textView1 and textView2. – Eugene Brusov Oct 05 '17 at 17:21
  • Tell me please, what constraint-layout version do you use @Cheticamp? – Eugene Brusov Oct 05 '17 at 17:22
  • @EugeneBrusov I think we had this conversation earlier with another one of your questions. I use the latest beta release: 1.1.0-beta2. If you don't want to run a beta release (understandable), you may want to consider 1.0.1 as the latest production release if you aren't already running it. – Cheticamp Oct 05 '17 at 17:26
  • Ah, I see now... Yep, 1.1.0-beta2 solves many problems except for it's in still in beta yet. Anyway thanks for testing this out for me! – Eugene Brusov Oct 05 '17 at 17:30
  • @EugeneBrusov I am curious about which ConstraintLayout version you are using. – Cheticamp Oct 05 '17 at 17:30
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/156036/discussion-between-eugene-brusov-and-cheticamp). – Eugene Brusov Oct 05 '17 at 17:31
  • @EugeneBrusov Look at the bottom of the answer. I added a fix for your setup. – Cheticamp Oct 05 '17 at 17:55
1

The gist of it is to use a packed chain, with a vertical bias of 0, so that the content of the chain will be at the top. Also, I'm not sure why you are using a FrameLayout -- you probably don't need to.

enter image description here

With 1.1.0-beta2:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorAccent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:scaleType="centerCrop"
        app:layout_constraintBottom_toTopOf="@+id/textView1"
        app:layout_constraintDimensionRatio="h,16:9"
        app:layout_constraintVertical_bias="0.0"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_chainStyle="packed"
        app:srcCompat="@android:color/darker_gray" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        android:text="Title"
        android:textAppearance="@style/TextAppearance.AppCompat.Headline"
        app:layout_constraintTop_toBottomOf="@+id/imageView"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintBottom_toTopOf="@+id/textView2" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        android:layout_marginBottom="24dp"
        android:text="Subtle"
        app:layout_constraintTop_toBottomOf="@+id/textView1"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintBottom_toBottomOf="parent" />

</android.support.constraint.ConstraintLayout>
Nicolas Roard
  • 8,339
  • 1
  • 28
  • 30
  • Thanks for this answer! Yep, packed chain fixes all the vertical margins in the requested layout even with constraint-layout v1.0.2. I used FrameLayout only for test purposes as a root layout since I wanted to see the way ConstraintLayout wraps content. I can use ConstraintLayout with `layout_height="wrap_content"` for example as a RecyclerView item. – Eugene Brusov Oct 06 '17 at 06:59
0

Try this one -> I removed app:layout_constraintBottom_toTopOf="@+id/textView1" in the ImageView and it works fine.

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:background="@color/colorAccent">

        <ImageView
            android:id="@+id/imageView"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:scaleType="centerCrop"
            app:srcCompat="@android:color/darker_gray"
            app:layout_constraintDimensionRatio="h,16:9"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent" />

        <TextView
            android:id="@+id/textView1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="24dp"
            android:layout_marginLeft="16dp"
            android:layout_marginRight="16dp"
            android:text="Title"
            android:textAppearance="@style/TextAppearance.AppCompat.Headline"
            app:layout_constraintTop_toBottomOf="@+id/imageView"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintBottom_toTopOf="@+id/textView2" />

        <TextView
            android:id="@+id/textView2"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:layout_marginLeft="16dp"
            android:layout_marginRight="16dp"
            android:layout_marginBottom="24dp"
            android:text="Subtle"
            app:layout_constraintTop_toBottomOf="@+id/textView1"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintBottom_toBottomOf="parent" />

    </android.support.constraint.ConstraintLayout>
</FrameLayout>
John Le
  • 1,116
  • 9
  • 12
0

Based on answers and comments posted in reply to this question and considering the fact constraint-layout v1.1.0 is still in beta, the best solution at this moment would be to use app:layout_constraintVertical_chainStyle="packed":

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <ImageView
            android:id="@+id/imageView"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:scaleType="centerCrop"
            app:srcCompat="@android:color/darker_gray"
            app:layout_constraintDimensionRatio="h,16:9"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintBottom_toTopOf="@+id/textView1"
            app:layout_constraintVertical_chainStyle="packed"/>

        <TextView
            android:id="@+id/textView1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="24dp"
            android:layout_marginLeft="16dp"
            android:layout_marginRight="16dp"
            android:text="Title"
            android:textAppearance="@style/TextAppearance.AppCompat.Headline"
            app:layout_constraintTop_toBottomOf="@+id/imageView"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintBottom_toTopOf="@+id/textView2" />

        <TextView
            android:id="@+id/textView2"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:layout_marginLeft="16dp"
            android:layout_marginRight="16dp"
            android:layout_marginBottom="24dp"
            android:text="Subtle"
            app:layout_constraintTop_toBottomOf="@+id/textView1"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintBottom_toBottomOf="parent" />

    </android.support.constraint.ConstraintLayout>
</FrameLayout>
Eugene Brusov
  • 17,146
  • 6
  • 52
  • 68