I am developing news app and I want to implement constrainlayout inside CardView and achieve ui the same as image below
but I could achieve what I want below my xml file
where I have implemented constrainlayout inside cardview
<TextView
android:id="#+id/articleTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/articleTitle"
tools:ignore="NotSibling" />
<TextView
android:id="#+id/articleAuthor"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:text="hhhhh"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/imageView" />
<TextView
android:id="#+id/articleImageView"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/articleTitle" />
<TextView
android:id="#+id/articleDescription"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:text="hhhhh"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/imageView" />
<ImageView
android:id="#+id/articleImageUrl"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="H,16:9"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="#id/articleTitle"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" />
below my xml ui output from layouteditor
What you need to achieve is not difficult at all (although, it's hard to tell because I don't know your project).
Based upon the image you provided, here's a rough approximation using basic Constraint Layout features (no Chains, or anything too fancy); again, I don't know the exact specs and requirements, but this should serve as a starting point.
Here's how the final product looks in the Android Studio Editor, I didn't run this, so there are some artifacts not 100% correctly rendered (like the borders of the CardView), because Android Studio does an "approximation" of how it looks:
Root Layout
You mentioned you wanted a CardView, so the root is naturally a MaterialDesign Card View:
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:background="#android:color/darker_gray"
android:elevation="4dp">
Constraint Layout
Inside the card view, there's one single viewGroup: a Constraint Layout
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/innerRoot"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/white">
This ConstraintLayout is going to contain all the Card's contents in a flat hierarchy. It matches its parent (the card) in width, but it wraps its height, just like the Card itself.
Top News Header, Icon, and subtext:
THere are various ways to achieve this, and depending upon your requirements, you may want to play with vertical chains, constraining the width, etc., to avoid text from overlapping each other, and/or to enable/disable multi-line support, or ellipsis, etc. None of this information can be inferred from your static image.
<ImageView
android:id="#+id/topFlameImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="Header title"
android:padding="8dp"
android:src="#drawable/ic_flash_on_black_24dp"
android:tint="#android:color/holo_red_light"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.textview.MaterialTextView
android:id="#+id/topTitleTextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Top News"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#id/topFlameImageView"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.textview.MaterialTextView
android:id="#+id/bottomTitleTextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Editor on duty: Dan"
android:textColor="#android:color/darker_gray"
app:layout_constraintBottom_toBottomOf="#id/topFlameImageView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#id/topFlameImageView"
app:layout_constraintTop_toBottomOf="#id/topTitleTextView" />
Notice it's just an ImageView, and two TextViews, one below the other, all constrained together.
Big Image
I didn't put an image, but did add a blue background representing the image. I gave it an arbitrary height of 250dp, but this is not mandatory, you may change this; it gives you an idea.
This image is constrained to be below the above header with "Top News", etc, and it spans the whole width of the card.
<ImageView
android:id="#+id/bigImage"
android:layout_width="0dp"
android:layout_height="250dp"
android:background="#android:color/holo_blue_dark"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/topFlameImageView" />
Title + Icon
Below the big image, there's what appears to be a Title (and its icon). Nothing special, just like the "header" above, an image and a text.
Here is where there's something that I didn't do: In your image, the text in this, aligns to the left/start, even below the icon; in this example, the TextView is constrained to the end/right of the icon, and so if it's multi-line, it will not "properly" justify its text to fit below the icon. In other words, in the image above, the word "Update" should be below the red "lightning bolt" icon, but it's not. (I think it looks better this way anyway... but I haven't thought how to make it look like what you exactly want). Using drawableStart in the TextView, doesn't give the same effect, so that's why I used a separate imageVIew for these "icons", to better control the image's placement.
<ImageView
android:id="#+id/titleImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:contentDescription="Title"
android:padding="8dp"
android:src="#drawable/ic_flash_on_black_24dp"
android:tint="#android:color/holo_red_light"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/bigImage" />
<com.google.android.material.textview.MaterialTextView
android:id="#+id/titleTextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Real Madrid provide Toni Kroos injury update"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#id/titleImageView"
app:layout_constraintTop_toTopOf="#id/titleImageView" />
User Avatar, Name, and Timestamp (?)
This is similar to the Title, and the Header at the beginning, except you want the timestamp (17 m) to be at the end/right of what appears to be the user name Onefootball.
<ImageView
android:id="#+id/userAvatarImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:contentDescription="Title"
android:padding="8dp"
android:src="#drawable/ic_account_circle_black_24dp"
android:tint="#android:color/holo_green_light"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/titleTextView" />
<com.google.android.material.textview.MaterialTextView
android:id="#+id/userNameTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Onefootball"
android:textColor="#android:color/black"
android:textSize="14sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="#id/userAvatarImageView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="#id/titleImageView"
app:layout_constraintTop_toTopOf="#id/userAvatarImageView" />
<com.google.android.material.textview.MaterialTextView
android:id="#+id/timestampTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:text="- 17m"
android:textColor="#android:color/darker_gray"
android:textSize="14sp"
app:layout_constraintBaseline_toBaselineOf="#id/userNameTextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="#id/userNameTextView" />
One image, one Text, another text; nothing fancy.
Closing the tags
Last but not least, you have to close the ConstraintLayout and the CardView...
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
And that's all.
Final Comment | Conclusion
At the beginning of this combo, I told you StackOverflow is not a Free Coding Site; this is still true, and I've made this effort because it seems like you are learning Android and I love helping people, but keep in mind that in general, it's much much better if you try firsts and come up with 20 different small questions as you go through it.
I would have personally tried to solve this in small bits (like I presented it above) and when something didn't behave as expected, it would have been easier to ask here "Hey look at this small thing, why doesn't it do X Y Z????" than to try to post the whole thing, and hope someone comes around and fixes it for you so you can copy paste the solution and forget about it.
I really hope you learn from this and don't just copy/paste it.
Good luck with your project.
Related
How to put an clickable image in between string using a single TextView.
Using SpannableString, I am able to color part of string. But how to add a colored image? Any suggestion would be really appreciated.
This is not possible for a single TextView element. TextViews are not meant to contain images in the middle of them.
You can, however, add drawable resources to the top, right/start, left/end, or bottom of a given TextView by leveraging the drawableTop, drawableBottom, etc. attributes. But again, no way of adding an image in the middle of a TextView by using only one of them.
If you really want that specific effect, I would group a few XML components into any ViewGroup like a ConstraintLayout to get exactly what you want; e.g.
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="#+id/text_part_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="first part of the text"
android:textSize="16dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#id/image"/>
<ImageView
android:id="#+id/image"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#color/white"
app:layout_constraintStart_toStartOf="#id/text_part_1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="#id/text_part_2"/>
<TextView
android:id="#+id/text_part_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="first part of the text"
android:textSize="16dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="#id/image"/>
</androidx.constraintlayout.widget.ConstraintLayout>
How do I remove the spacing on the top and bottom of the texts? I want to the two texts to touch each other or at least reduce the spacing between the texts.
I've looked at other posts recommending setting android:includeFontPadding="false", but that does not work.
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="96sp"
android:text="TEXT1"
android:background="#color/primaryColor"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="96sp"
android:text="TEXT2"
android:background="#color/secondaryColor"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/textView" />
The problem is that's not just empty space - it's the ascent and descent for the font, where things like the lower part of a g goes. The TextView has to have that space because it doesn't know you're not going to be using it. includeFontPadding affects some accents on top of the ascent, so you can remove a little bit of the space, but the rest of it's required.
Short of getting a font with no ascent and descent, honestly I think the best thing you can do is constrain the top of the lower TextView to the top of the upper one, and add a marginTop value that shifts it down where you want it. Use an sp value instead of dp so it stays relative to the user's font size preferences - and if you change the font you'll need to tweak it. And the backgrounds will have to be separate, behind the textviews, if you're using those
If you absolutely want this at any cost, then you can do the following, I have not checked if it will work on different screen sizes . But you can attach both of their top to the same view, can be parent, then make the background transparent, if you chose different colours then this wont work, keep the text in all caps so that the regular alphabets can't go any higher or lower. Keep the margin according to the text size which you will give in dp. This is probably "I want this in any way" approach rather than an acceptable approach.
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="95dp"
android:text="TEXT1"
android:background="#android:color/transparent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginTop="0dp"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:text="TEXT2"
android:textSize="95dp"
android:layout_marginTop="75dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
You can do some clever stuff with a Space view to make this work:
<TextView android:id="#+id/textView1"
[other TextView stuff]
app:layout_constraintTop_toTopOf="parent"/>
<Space android:id="#+id/space"
android:layout_marginBottom="20dp"
app:layout_constraintBottom_toBottomOf="#id/textView1"/>
<TextView android:id="#+id/textView2"
[other TextView stuff]
app:layout_constraintTop_toBottomOf="#id/space"/>
Then fiddle with the margin parameter in the Space view until the text is where you want it.
I have this layout that I want to use as a header for navigation bar:
<?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="164dp">
<ImageView
android:id="#+id/app_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="24dp"
android:layout_marginStart="24dp"
android:layout_marginTop="16dp"
android:adjustViewBounds="false"
android:scaleType="center"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#mipmap/ic_launcher" />
<TextView
android:id="#+id/first_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginStart="24dp"
android:layout_marginTop="16dp"
android:text="Name"
android:textAppearance="#style/TextAppearance.AppCompat.Headline"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="#+id/app_icon" />
<ImageView
android:id="#+id/credits_material_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp"
android:scaleType="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:srcCompat="#drawable/ic_dollar_coin_stack" />
<TextView
android:id="#+id/credits_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp"
android:text="Credits"
android:textStyle="italic"
android:textAppearance="#style/TextAppearance.AppCompat.Body2"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="#+id/credits_material_icon" />
<TextView
android:id="#+id/credits_available"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:text="TextView"
android:textAppearance="#style/TextAppearance.AppCompat.Body2"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="#+id/credits_label" />
</android.support.constraint.ConstraintLayout>
In the layout editor, the layout looks like:
But on a device, I am getting something like this:
The encircled portion is the layout under concern. Under that, you can see a ListView but that is a child of LinearLayout so that is a separate story.
So, my question is that why none of my ImageViews are displaying at all?
Things I have tried:
I have tried moving the ImageViews around with no improvement.
I checked with the layout hierarchy with the Layout inspector. Turns out, it shows a literal dot in place of both the ImageViews.
I have tried manually setting the height of this layout to a very large number to solve any accommodation related problems if there are any.
The answer is simple:
When in doubt, use android.support.v7.widget.AppCompatImageView
I thought that Android docs advising against its use in general was something to be taken seriously.
This will automatically be used when you use ImageView in your
layouts. You should only need to manually use this class when writing
custom views.
Another place I read that you are supposed to be extending from AppCompatActivity to enable this behavior. My Activities DO extend from AppCompatActivity but still I spent so much time thinking that maybe something is buggy with ConstraintLayout after all.
NO. My beloved ConstraintLayout hasn't lost its chivalry yet. :)
So, when in doubt, I reiterate,
Use android.support.v7.widget.AppCompatImageView
Some other answers saying the same thing:
Android vector drawable app:srcCompat not showing images
app:srcCompat does not work for ImageView
I recently started using ConstraintLayout. As I discovered, most of the features are pretty straight forward, and well explained in the docs with samples, text and video tutorials and all.
The thing that got in my mind is how to I solve this 'puzzle' as elegant as possible?
As you can see, in the right section of the layout, I have multiple Views aligned left. On the last but one row, there are 3 Views aligned horizontally (they are also aligned TOP between each other).
Problem is: if I set first View's visibility from that row as GONE, the other two (in the same row), go left as expected, but the one underneath (last row in the vertical alignment) goes over the row before (because its constraintTop property is set as bottom of the View set as GONE).
The only solution I can think of is using a ViewGroup to group those 3 Views and add the constraint to last row View to it.
Am I missing some property on ConstraintLayout which could help my case? Maybe some sort of fallback (or multiple) constraints if one of them is set on a GONE View?
Sorry if my explanation seem quite abstruse, maybe the pictures will help you more :)
LE: Added layout: https://gist.github.com/DoruAdryan/7e7920a783f07b865489b1af0d933570
You can use the new Barriers feature of ConstraintLayout.
<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.support.v7.widget.AppCompatImageView
android:id="#+id/iv_item_small_product_image"
android:layout_width="113dp"
android:layout_height="113dp"
android:layout_marginLeft="7dp"
android:layout_marginStart="7dp"
android:background="#android:drawable/btn_radio"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.v7.widget.AppCompatImageView
android:id="#+id/iv_row_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:background="#android:drawable/bottom_bar"
app:layout_constraintLeft_toRightOf="#+id/iv_item_small_product_image"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ro.emag.android.views.FontTextView
android:id="#+id/tv_row_2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="3dp"
android:ellipsize="end"
android:maxLines="2"
app:layout_constraintLeft_toRightOf="#+id/iv_item_small_product_image"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/iv_row_1"
app:layout_goneMarginTop="0dp"
tools:text="Some text long enough to be split on multiple lines on some devices." />
<android.support.v7.widget.AppCompatRatingBar
android:id="#+id/rb_row_3_1"
style="#style/Widget.AppCompat.RatingBar.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="9dp"
android:isIndicator="true"
android:numStars="5"
android:stepSize="0.1"
app:layout_constraintLeft_toRightOf="#+id/iv_item_small_product_image"
app:layout_constraintTop_toBottomOf="#id/tv_row_2" />
<TextView
android:id="#+id/tv_row_3_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:layout_marginStart="6dp"
android:layout_marginTop="9dp"
app:layout_constraintLeft_toRightOf="#+id/rb_row_3_1"
app:layout_constraintTop_toBottomOf="#id/tv_row_2"
tools:text="106" />
<TextView
android:id="#+id/tv_row_3_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:layout_marginStart="6dp"
android:layout_marginTop="9dp"
app:layout_constraintLeft_toRightOf="#+id/tv_row_3_2"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/tv_row_2"
app:layout_goneMarginLeft="0dp"
app:layout_goneMarginStart="0dp"
tools:text="Options available" />
<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="rb_row_3_1, tv_row_3_2, tv_row_3_3" />
<TextView
android:id="#+id/tv_row_4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="3dp"
android:ellipsize="end"
android:maxLines="1"
app:layout_constraintLeft_toRightOf="#+id/iv_item_small_product_image"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/barrier"
tools:text="Some text on last row" />
</android.support.constraint.ConstraintLayout>
Now, the last row is depending on the barrier instead of one of the views of the third row. As the barrier is depending on the three views of the second row, you won't have the gone margin problem.
Plus, i noticed that you don't need the guideline. The right segment can depend on the imageview directly.
In case you are not familiar with Barriers, here's a link to help you out.
As this feature is available only in the 1.1.0 beta1 release of ConstraintLayout, don't forget to add this line to your build.gradle file.
compile 'com.android.support.constraint:constraint-layout:1.1.0-beta1'
make sure to include maven { url "https://maven.google.com" }
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!).