Is there a possibility (in ConstraintLayout) to let a view grow only as long as there is space for another view at his right?
The use case is to have a value and unit TextViews besides each other. The value TextView should be able to grow as long as there is space for the unit. If there is not enough space, the value should be cut.
I've tried it with chains and some other things but can't get it done. The value doesn't stop growing and then the unit is not visible anymore. Here's the current code:
<TextView
android:id="#+id/value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:lines="1"
app:layout_constraintBaseline_toBaselineOf="#+id/unit"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="#id/unit"
tools:text="12533939532" />
<TextView
android:id="#+id/unit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintLeft_toRightOf="#id/value"
app:layout_constraintRight_toRightOf="parent"
tools:text="km" />
yes you can by using match_constraint (0dp) which equal to match_parent for other layout, so by using match_constraint we set weight for first view which will occupies all available space also add
app:layout_constraintWidth_default="wrap"
to apply default width behavior as wrap_content
here is code with change
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
android:id="#+id/value"
android:layout_width="0dp"
app:layout_constraintWidth_default="wrap"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:lines="1"
app:layout_constraintBaseline_toBaselineOf="#+id/unit"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="#id/unit"
tools:text="12533939532" />
<TextView
android:id="#+id/unit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
app:layout_constraintLeft_toRightOf="#id/value"
app:layout_constraintRight_toRightOf="parent"
tools:text="km" />
</android.support.constraint.ConstraintLayout>
got some explanation from site
Better view dimension controls
The new available behaviors when a dimension is set to 0dp (MATCH_CONSTRAINT). As before, both endpoints (left/right or top/bottom) need to be connected to targets.
layout_constraintWidth_default = spread (default, similar to the previous behavior)
layout_constraintWidth_default = wrap
layout_constraintHeight_default = spread
layout_constraintHeight_default = wrap
Wrap provides a significant new behaviour, with the widget resizing as if wrap_content was used, but limited by the connected constraints. A widget will thus not grow beyond the endpoints.
http://tools.android.com/recent/constraintlayoutbeta5isnowavailable
Related
I am trying to see examples of the use of app:layout_constrainedWidth="true" in a ConstraintLayout, but I am not undesrtanding the use of this attribute. In what ocasions should I use this attribute set to true?
Thanks for the help
app:layout_constrainedWidth="true" is make ConstraintLayout respect the constraints of a view with a width of `wrap_content'. Here is a fuller explanation.
WRAP_CONTENT : enforcing constraints (Added in 1.1)
If a dimension is set to WRAP_CONTENT, in versions before 1.1 they will be treated as a literal dimension -- meaning, constraints will not limit the resulting dimension. While in general this is enough (and faster), in some situations, you might want to use WRAP_CONTENT, yet keep enforcing constraints to limit the resulting dimension. In that case, you can add one of the corresponding attribute:
app:layout_constrainedWidth="true|false"
app:layout_constrainedHeight="true|false"
Let's say that we have the following layout:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:text="Left TextView"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.8" />
<TextView
android:id="#+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:text="I am a TextVIew with some very long text. How is it going to be handled?"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="#+id/textView"
app:layout_constraintTop_toTopOf="#+id/textView" />
</androidx.constraintlayout.widget.ConstraintLayout>
This is displayed as
As you can see, the right TextView text is cut off - the right constraint is not honored. Now let's add app:layout_constrainedWidth="true" to the right TextView. Now will see
The view is still wrap_content, but the right constraint is honored.
I have the following XML code , I couldn't make 'summaryViewPager' fill the remaining space vertically, until the bottom of the screen :
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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">
<com.google.android.material.card.MaterialCardView
android:id="#+id/mainCardView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
android:background="#666266"
android:padding="10dp"
app:cardCornerRadius="20dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="3dp"
android:layout_marginLeft="3dp"
android:layout_marginTop="2dp"
android:text="#string/category"
android:textColor="#FFBA93"
android:textSize="20sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="#+id/cardView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
android:background="#666266"
android:padding="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/mainCardView">
<Button
android:id="#+id/shareButton"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginStart="5dp"
android:layout_marginLeft="5dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="5dp"
android:layout_marginRight="5dp"
android:background="#drawable/ic_share"
app:layout_constraintEnd_toStartOf="#+id/copyButton"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="#+id/seenImageView"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginStart="3dp"
android:layout_marginLeft="3dp"
android:layout_marginTop="15dp"
android:layout_marginEnd="5dp"
android:layout_marginRight="5dp"
android:contentDescription="#string/todo"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="#+id/favoriteButton"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/unseen" />
</com.google.android.material.card.MaterialCardView>
<androidx.viewpager2.widget.ViewPager2
android:id="#+id/summaryViewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="2dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/cardView2" />
</androidx.constraintlayout.widget.ConstraintLayout>
The above code doesn't show the PageViewer at all below cardView2 , however when I set android:layout_height="500dp it does show PageViewer, but it doesn't fill the whole screen.
Initial Thoughts
I copy pasted your Layout into Android Studio 4.x, replaced all #string references with "something", and all #drawables with an existing one (from #android:drawable/) so my layout would render.
From what I see, it looks correct:
I noticed some inconsistencies in your Layout.
CardView Number 1 (top)
Careful with Padding on a CardView (don't know your min/max API so, not sure if this applies to you).
Your CardView has no constrain for its BOTTOM, it's left to "whatever size you compute after wrapping" (Height = wrap, Bottom_To = null).
This ^ means that for the CardView to have a height, all its innerwidgets must compute their sizes, so the top card view knows how much size + margin + padding it needs. It doesn't depend on OTHER widgets (that are not children) because its constrains are all to the parent. (rather it only needs its parent).
CardView Number 2 (bottom)
This cardView wraps all its dimensions but has the same issue as the one above, it doesn't constraint its height (except to be pinned at the bottom of the previous one, CardView 1). Again, this is fine, so as long as nobody depends on this (which is not true). This one has to wait on more widgets to know its size, because it has to wait on the CardView1 to know how much space is left, and also needs to know how much its children need. It's not too hard because both (the ImageView and the Button) have fixed sizes (20 and 30 dp respectively) + margins/padding.
The children of a MaterialCardView cannot/should not/must not use constraints because a CardView is not a ConstraintLayout, rather a glorified FrameLayout, which can only hold ONE child (or if it has more, it will put them on on top of the other). So all those constraints (for the shareButton and seenImageView) are ignored.
The solution to the above, is to have an inner ConstraintLayout as the sole child of a CardView, and inside this inner CL, put all your children and their constraints. The inner ConstraintLayout should have its width/height as either wrap_content or match_parent so they use the constraints of the parent. Since htey have fixed sizes, this is not an issue. (and if they didn't it wouldn't be an issue, but would need another measure pass).
Regardless of this, this second CardView is able to calculate its height, because its children are reporting a size of 20+30 (overlapped) + 15 margin top (image) so.. all this combined is likely 45dp~ of height (since they overlap only the biggest numbers apply here).
All the constraints are ignored for these two children.
ViewPager (bottom)
Finally we reach the VPager. This viewPager is match_parent for its width (since you have constraints to the start/end, you should just use 0dp). And it has wrap_content for its height.
layout_height=wrap_content -> this is a problem here. Because the viewPager doesn't (at the time of layout pass/measure) yet know what its contents are going to be. So you probably want this to be 0dp and let the ViewPager use all available space after the above has been calculated.
The marginTop you have here, will not work as it is, because the CardView 1 and 2 have no bottom constrain, so this one would have to create yet another layout/measure pass after it's all said and done to be able to apply a margin (that's how it works).
Ok Enough Rant - what can you do?
I'd "fix" the layout by adding the correct constraints and -if needed- use a VerticalChain and biasing for all widgets.
I'd fix the middle (Cardview 2) contents by wrapping the textview and imageView in a ConstraintLayout.
I'd remove left/right and replace with start/end (unless you target API 16 or below).
I'd set the ViewPager to 0dp on both dimensions.
The children of your CardView2 refer to copyButton and favoriteButton but these don't exist in the Layout you pasted, so I assume you have more buttons there).
Full Version (modified)
And in case you wonder, here's what I did ( I added a color to the VP's background so it was easier to "see").
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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">
<com.google.android.material.card.MaterialCardView
android:id="#+id/mainCardView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
app:layout_constraintVertical_chainStyle="packed"
android:background="#666266"
android:padding="10dp"
app:cardCornerRadius="20dp"
app:layout_constraintBottom_toTopOf="#id/cardView2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="3dp"
android:layout_marginTop="2dp"
android:text="Category"
android:textColor="#FFBA93"
android:textSize="20sp"
android:textStyle="bold" />
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="#+id/cardView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
android:background="#666266"
android:padding="10dp"
app:layout_constraintBottom_toTopOf="#id/summaryViewPager"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/mainCardView">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/innerCardView2Root"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="#+id/shareButton"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginStart="5dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="5dp"
android:background="#android:drawable/ic_menu_share"
app:layout_constraintEnd_toStartOf="#+id/seenImageView"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="#+id/seenImageView"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginStart="3dp"
android:layout_marginTop="15dp"
android:layout_marginEnd="5dp"
android:contentDescription="#null"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/shareButton"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#android:drawable/ic_menu_search" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
<androidx.viewpager2.widget.ViewPager2
android:id="#+id/summaryViewPager"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="2dp"
android:background="#color/colorSecondary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/cardView2" />
</androidx.constraintlayout.widget.ConstraintLayout>
I'm having an issue sizing children in a ConstraintLayout. I have 3 views:
TextView (item_quantity): I want this to grow indefinitely, but not push the TextInputLayout off the screen
TextInputLayout (data_entry_layout): I want this to fill all available horizontal space and have a minimum width of 120dp no matter what
ImageView (camera_scan): This will not grow, just needs to not get pushed off the screen
If item_quantity has short text, I want it to look like the image below. I want data_entry_layout to fill all available space.
If item_quantity has long text, I want it to fill and grow but I want the data_entry_layout to never be smaller than 120dp. I want it to honor the minWidth. So, I want it to look like this:
Here is my current configuration:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
android:paddingTop="10dp"
android:paddingBottom="10dp">
<TextView
android:id="#+id/item_quantity"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constrainedWidth="true"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#id/data_entry_layout"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintVertical_chainStyle="spread_inside"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:text="90,000 Boxes of Stuff Are Needed"
android:textColor="#color/color_on_background"
android:textSize="#dimen/workflow_item_view_item_quantity_text_size" />
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/data_entry_layout"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toStartOf="#id/camera_scan"
app:layout_constraintStart_toEndOf="#id/item_quantity"
app:layout_constraintVertical_chainStyle="spread_inside"
android:contentDescription="#string/disable_realwear_asr"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:minWidth="120dp"
app:errorIconDrawable="#null">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/data_entry"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="#dimen/activity_instruction_data_entry_text_size"/>
</com.google.android.material.textfield.TextInputLayout>
<ImageView
android:id="#+id/camera_scan"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginEnd="5dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="#id/data_entry_layout"
app:layout_constraintTop_toTopOf="#id/data_entry_layout"
android:background="#android:color/transparent"
android:clickable="true"
android:foreground="#drawable/ripple_selector"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:src="#drawable/qrcode_scan"
android:visibility="visible"
tools:ignore="ContentDescription,KeyboardInaccessibleWidget" />
</androidx.constraintlayout.widget.ConstraintLayout>
If I set item_quantity's layout_width to 0dp then the UI works with lots of text, but takes up too much horizontal space with short text:
If I set item_quantity's layout_width to wrap_content then the UI works with short text, but pushes the data_entry_layout off the screen with large text:
I must be missing something simple. Is there a way I can get both of these situations to do what I want?
Rather than use the android:minWidth property try using app:layout_constraintWidth_min. ConstraintLayout seems to either ignore or overrule certain properties with the "android" namespace when it comes to sizing of elements.
I have a ConstraintLayout where its height is wrap_content.
I want its height to be able to collapse or expanding, according to its Child's height. Simple and common enough, right?
Now I have a layout which looks like this:
(First of all, please ignore the abnormal super large margin at the bottom. As you can see, the margin is just 16dp but the preview renders a very large margin.)
My problem is, if the big rectangle's visibility is set to gone,
According to the documentation of ConstraintLayout, if I set its goneMarginTop to a certainValue, it will retain that margin even when its visibility is gone. So that my Request Date will have some space to the bottom of parent.
However, this does not work as expected. Request Date sticked to the bottom of its parent:
(This is again a broken preview. In my real app, I am able to see a complete Request Date)
Have I done something wrong? Here is my complete code:
<?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="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:background="#color/colorBasicGrey"
android:layout_marginBottom="2dp">
<View
android:id="#+id/item_indicator"
android:layout_width="8dp"
android:layout_height="8dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:background="#color/white"
android:layout_marginTop="24dp"
android:layout_marginLeft="24dp"/>
<TextView
android:id="#+id/group_member_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/group_member_join_group_request"
app:layout_constraintTop_toBottomOf="#id/item_indicator"
app:layout_constraintBottom_toTopOf="#id/item_indicator"
app:layout_constraintLeft_toRightOf="#id/item_indicator"
android:layout_marginLeft="8dp"
style="#style/general45"/>
<TextView
android:id="#+id/group_member_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/general45"
android:textAllCaps="true"
app:layout_constraintBaseline_toBaselineOf="#id/group_member_label"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginLeft="180dp"
tools:text="ABCDEFGHIJK"/>
<TextView
android:id="#+id/group_request_date_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/group_member_request_date_label"
app:layout_constraintTop_toBottomOf="#id/group_member_label"
app:layout_constraintLeft_toLeftOf="#id/group_member_label"
android:layout_marginTop="8dp"
style="#style/general45"/>
<TextView
android:id="#+id/group_request_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/general45"
android:textAllCaps="true"
app:layout_constraintBaseline_toBaselineOf="#id/group_request_date_label"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginLeft="180dp"
tools:text="28/10/2017"/>
<LinearLayout
android:id="#+id/admin_button_container"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_marginBottom="16dp"
android:layout_marginLeft="24dp"
android:layout_marginRight="24dp"
android:layout_marginTop="12dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/group_request_date_label"
app:layout_constraintVertical_bias="0.0"
app:layout_goneMarginTop="16dp"
app:layout_goneMarginLeft="24dp"
app:layout_goneMarginRight="24dp"
app:layout_goneMarginBottom="0dp"
android:visibility="gone">
<!--To simplify the question, I hided elements inside this LinearLayout-->
</LinearLayout>
</android.support.constraint.ConstraintLayout>
Figured it out.
goneMargin is used to indicate the margin to a GONE target, instead of itself being GONE.
Therefore in fact I should put the goneMargin attributes in the Request Date instead of the large rectangle.
I have a XML layout for a ViewHolder inside a RecyclerView.
This layout's root is a ConstraintLayout whose height is set to wrap_content.
Inside this flat hierarchy there are 3 textviews and an image view with a fixed height; think of:
<ConstraintLayout>
<TextView height=wrap>
<TextView height=wrap>
<TextView height=wrap>
<ImageView height=150dp>
</ConstraintLayout>
It's a relatively simple layout. In beta4 this is how it looks in the Designer (and eventually at runtime, each recyclerView cell):
Apologies for the "red tape" but it's NDA blah blah.
That being said, the elements are:
The 3 text views (red taped with a nice purple background)
The ImageView with 150dp height is the gray thing.
The Purple background was applied to the root ConstraintLayout. All nice.
Now this is how it looks, without a single modification with Beta 5:
As you can see the Purple (root) Constraint Layout is now "confused" and doesn't wrap content as it used to.
Things I tried:
Adding app:layout_constraintHeight_default="wrap" to the ConstraintLayout (and spread too). Didn't make a difference.
The ImageView has a app:layout_constraintBottom_toBottomOf="parent" constraint that I tried removing, didn't make a difference either.
Revert back to beta4 :)
For the record, this is the full layout (id's have been renamed for red-tape reasons and no tools:text or similar due to the same reasons). The layout is otherwise exactly the same.
<?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="wrap_content"
android:background="#color/colorAccent">
<TextView
android:id="#+id/toplabel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text=""
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="#+id/top_bottom_label"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="#+id/top_right_label"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/top_right_label"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginTop="8dp"
android:ellipsize="end"
android:gravity="end"
android:maxLines="1"
android:text=""
app:layout_constraintBottom_toTopOf="#+id/top_bottom_label"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintLeft_toRightOf="#+id/toplabel"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed" />
<TextView
android:id="#+id/top_bottom_label"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginTop="8dp"
android:ellipsize="end"
android:gravity="end"
android:maxLines="1"
android:text=""
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintLeft_toRightOf="#+id/toplabel"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/top_right_label" />
<ImageView
android:id="#+id/imageview"
android:layout_width="0dp"
android:layout_height="150dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/top_bottom_label"
app:srcCompat="#android:color/darker_gray" />
</android.support.constraint.ConstraintLayout>
Am I supposed to do something different? (I know I can replace this with a RelativeLayout and probably do the same, but anyway… I believe in ConstraintLayout!) :)
I filed a bug about this and I got a workaround.
It's a regression and will be fixed (we hope) but… turns out my Chain is also incorrectly defined. My top_bottom_label does not have a bottom endpoint, and according to the documentation elements in a chain should be connected on both endpoints.
So I added app:layout_constraintBottom_toTopOf="#id/imageview" to the top_bottom_label and this seems to work for my case. I have, effectively added the imageView to the chain, even do I don't really care much for it. It works for now.
Update February 14th 2017: The ConstraintLayout team # Google fixed the issue in master. It will likely be fixed in a next release. (Thanks!).