How to constraint a view min width equal to height in ConstraintLayout? - android

I have a TextView need to set the min width equal to the height, that means the view is square when the width <= height, and rectangle when the width > height.
now I hardcode the min width via app:layout_constraintWidth_min="20dp" but seems not work well for all phones.
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintWidth_min="20dp"
android:gravity="center_horizontal"/>
It's there has a better solution to constraint it and no need hardcode?
Inspired by #Mike087 the following code finally worked
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/c_FF4E4E"
android:gravity="center_horizontal"
android:text="22222222"
android:textColor="#color/c_F"
android:textSize="12sp"
app:layout_constrainedHeight="true"
app:layout_constrainedWidth="true"
app:layout_constraintDimensionRatio="w,1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_min="wrap" />

Try this code:
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constrainedHeight="true"
app:layout_constraintHeight_max="20dp"
app:layout_constraintDimensionRatio="1"
android:gravity="center_horizontal"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"/>

As a variant you can try to add a LayoutChangeListener and inside of it check the view size and then set app:layout_constraintDimensionRatio property for the view

Related

Constraint layout min width makes view take all available space when its width is below the minimum

I have a CardView inside a ConstraintLayout, and I want the CardView to have a width of 70%, a min width of 300dp, and a max of 450dp.
The max works fine, if 70% is more than 450dp, the CardView width is set to 450dp.
The min width however, behaves very strangely.
When 70% is less than 300dp, instead of making the CardView 300dp wide, it makes it as wide as the available space, so 100%.
Here is the CardView inside the layout:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.card.MaterialCardView
android:id="#+id/balanceCard"
android:layout_width="0dp"
android:layout_height="0dp"
app:cardCornerRadius="40dp"
app:cardElevation="15dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_min="300dp"
app:layout_constraintWidth_percent="0.7"/>
<androidx.constraintlayout.widget.ConstraintLayout/>
This is the layout with min width of 280dp
And this is the layout with min width of 300dp
I don't know what is happening, and I would appreciate any help.
This looks like a bug to me. The width of the CardView is incorrect when the minimum width exceeds 70% of the layout's width. For a Nexus 6 emulator (dp==3.5px), the ConstraintLayout width would be 1440px and 70% of that is 1008px. (I am using px instead of dp because I think that it makes what's happening clearer.)
When the minimum width is set to 288dp (1008px), everything looks good.
<View
android:id="#+id/balanceCard"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#android:color/holo_blue_light"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_min="288dp"
app:layout_constraintWidth_percent="0.7" />
I am using a straight View instead of a CardView for simplicity.
However, if we set the minimum width to 289dp (1011.5px), we see the problem.
Notice that 288dp (1008px) is equal to 70% of the layout's width (1008px) while 289dp (1011.5px) is greater than 70% of the layout's width.
It is interesting that, if we keep the minimum width at 289dp but remove the end constraint, the width is correct:
<View
android:id="#+id/balanceCard"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#android:color/holo_blue_light"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_min="289dp"
app:layout_constraintWidth_percent="0.7" />
I will note that I am using version 2.1.4 of ConstraintLayout.
The only work-around that I can see One work-around is, upon layout, check the width of the view and if it exceeds 70% of the layout's width, set the width to the minimum width that you want.
Another work-around that is more complex but involves just XML is to split the 70% behavior and the minimum width into two separate Space views. You can then set a barrier to the start and end of these two views and constrain the card view to the barriers. Remove the minimum width and 70% width attributes from the card view. This looks like this:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Space
android:id="#+id/spacePct"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent="0.7" />
<Space
android:id="#+id/spaceMinwidth"
android:layout_width="289dp"
android:layout_height="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<androidx.constraintlayout.widget.Barrier
android:id="#+id/barrierStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="start"
app:constraint_referenced_ids="spacePct,spaceMinwidth"/>
<androidx.constraintlayout.widget.Barrier
android:id="#+id/barrierEnd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="end"
app:constraint_referenced_ids="spacePct,spaceMinwidth"/>
<View
android:id="#+id/balanceCard"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#android:color/holo_blue_light"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="#id/barrierEnd"
app:layout_constraintStart_toStartOf="#id/barrierStart"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
If you agree with my assessment, you may want to consider submitting a bug report on the Issue Tracker, but that is totally up to you.

Android - Constraint Layout - margins vs layout_constraintWidth_percent

This is a question specifically for ConstraintLayout -
We can use margins as an attribute or layout_constraintWidth_percent as an attribute while working with width for an UI element.
Example - I have a button in centre of my UI which have some empty space to its left and right. Say something like this -
Approach1- uses "marginLeft" and "marginRight"
<Button
android:id="#+id/button"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_marginLeft="24dp"
android:layout_marginRight="24dp"
android:text="#string/button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
or
Approach2- uses "app:layout_constraintWidth_percent"
<Button
android:id="#+id/button"
android:layout_width="0dp"
android:layout_height="40dp"
app:layout_constraintWidth_percent="0.8"
android:text="#string/button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
Which of the following ways will be a more efficient way to render the UI element?
For efficiency of the two methods, there won't be any difference, at least that you will be able to measure, between the two (IMO), but the two methods are not the same.
Settting
android:layout_marginLeft="24dp"
android:layout_marginRight="24dp"
will place margins of 24dp to the right and left of the ConstraintLayout regardless of the ConstraintLayout's width. The view's width will take up the remainder of the width which will vary according to the width of the ConstraintLayout.
If you set
app:layout_constraintWidth_percent="0.8"
then the view's width will be 80% of the ConstraintLayout's width and each margin (left and right) will effectively be 10% of the ConstraintLayout's width (1/2 of 20%). So, the width of the view and it's margins will vary based upon the width of the ConstraintLayout.
If it really doesn't matter to your design then just pick one. But since there is a difference in how the two layout, I would look at the layout on the smallest screen you support and the largest and include any other alternate layout for landscape/portrait, etc. You may find that there is a good reason to prefer one over the other.
In case you have more complex structure of the ConstraintLayout layout_constraintWidth_percent will continue measure percents from the ConstraintLayout's width, not from the width it occupies.
For instance, I want to draw this picture:
<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="wrap_content">
<View
android:id="#+id/left"
android:layout_width="50dp"
android:layout_height="20dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="#+id/top"
android:layout_width="0dp"
android:layout_height="20dp"
android:layout_marginStart="20dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#id/left"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="#+id/bottom"
android:layout_width="0dp"
android:layout_height="20dp"
android:layout_marginTop="10dp"
app:layout_constraintStart_toStartOf="#id/top"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#id/top"
app:layout_constraintWidth_percent="0.8" />
</androidx.constraintlayout.widget.ConstraintLayout>
Then you will get bottom rectangle wider, than upper.

Make ViewPager Fill The Remaining Space In a ConstraintLayout

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>

Issue in ConstraintLayout implementation

I expect layout_constraintDimensionRatio to work with layout_constraintWidth_percent. But not working as expected. For example create a square view, which width is half of parent width.
<Button
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constrainedHeight="true"
app:layout_constrainedWidth="true"
app:layout_constraintDimensionRatio="H,1:1"
app:layout_constraintWidth_default="percent"
app:layout_constraintWidth_percent="0.5" />
I am reading following from android.support.constraint.ConstraintLayout
private void setChildrenConstraints() {
...............
if(layoutParams.dimensionRatio != null) {
widget.setDimensionRatio(layoutParams.dimensionRatio);
}
widget.setHorizontalWeight(layoutParams.horizontalWeight);
widget.setVerticalWeight(layoutParams.verticalWeight);
widget.setHorizontalChainStyle(layoutParams.horizontalChainStyle);
widget.setVerticalChainStyle(layoutParams.verticalChainStyle);
widget.setHorizontalMatchStyle(layoutParams.matchConstraintDefaultWidth, layoutParams.matchConstraintMinWidth, layoutParams.matchConstraintMaxWidth, layoutParams.matchConstraintPercentWidth);
widget.setVerticalMatchStyle(layoutParams.matchConstraintDefaultHeight, layoutParams.matchConstraintMinHeight, layoutParams.matchConstraintMaxHeight, layoutParams.matchConstraintPercentHeight);
}
}
I think, setDimensionRatio should be called after setVerticalWeight for this. Is this a bug inside ConstraintLayout. Or Am I missing any thing?
If you want your View to be 50% of width Add Guideline with orientation="vertical"
E.g.
<ImageView
android:id="#+id/imageView7"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toStartOf="#+id/guideline4"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/attach_audio" />
<android.support.constraint.Guideline
android:id="#+id/guideline4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
Imageview of 50% width of parent
Can you post more about your ConstraintLayout attributes? According to what I know and the official document,
You can also define one dimension of a widget as a ratio of the other one. In order to do that, you need to have at least one constrained dimension be set to 0dp (i.e., MATCH_CONSTRAINT), and set the attribute layout_constraintDimensionRatio to a given ratio.
Have you set the layout_width to 0dp ?
with the help of Dipali's answer I could make the design as I want.
<Button
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="H,1:1"
app:layout_constraintRight_toLeftOf="#+id/guide_line"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.constraint.Guideline
android:id="#+id/guide_line"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
But what I found is : layout_constraintDimensionRatio will not work with layout_constraintWidth_percent or layout_constraintHorizontal_chainStyle etc.

TextView inside ConstraintLayout clips text and layout_margin cant not be shown correctly

I use :
compile 'com.android.support.constraint:constraint-layout:1.0.2'
The main problems are:
layout_margin can't be shown correctly;
child textview's text is clipped.
Details as below:
This is my xml:
<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="wrap_content"
android:background="#android:color/darker_gray"
android:padding="8dp">
<ImageView
android:id="#+id/reviewer_avatar"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="#color/colorAccent"
android:contentDescription="#string/avatar"
android:layout_margin="8dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="#+id/reviewer_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/reviewer_name"
android:textSize="16sp"
app:layout_constraintBottom_toTopOf="#+id/comment_floor"
app:layout_constraintLeft_toRightOf="#+id/reviewer_avatar"
app:layout_constraintTop_toTopOf="#+id/reviewer_avatar"
app:layout_constraintVertical_chainStyle="packed"/>
<TextView
android:id="#+id/comment_floor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/reviewer_floor_text"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="#+id/reviewer_avatar"
app:layout_constraintLeft_toRightOf="#+id/reviewer_avatar"
app:layout_constraintTop_toBottomOf="#+id/reviewer_name"/>
<TextView
android:id="#+id/comment_period"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:text="#string/comment_period_text"
android:textSize="12sp"
app:layout_constraintLeft_toRightOf="#+id/comment_floor"
app:layout_constraintTop_toBottomOf="#+id/reviewer_name"/>
<TextView
android:id="#+id/comment_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/large_text"
android:textSize="16sp"
app:layout_constraintLeft_toRightOf="#+id/reviewer_avatar"
app:layout_constraintTop_toBottomOf="#+id/reviewer_avatar"/>
</android.support.constraint.ConstraintLayout>
This is my screenshot:
Here are mainly two problems
You missing to set right constraint for view with parent
There was an bug in ConstraintLayout with wrap_content which is resolved , now you have to use match_constraint(0dp) and layout_constraintWidth_default property to solve this issue
add below two properties to largetext view
android:layout_width="0dp"
app:layout_constraintWidth_default="wrap"
app:layout_constraintRight_toRightOf="parent"
So your largetext view would be like
<TextView
android:id="#+id/comment_content"
android:layout_width="0dp"
app:layout_constraintWidth_default="wrap"
android:layout_height="wrap_content"
android:text="#string/large_text"
android:textSize="16sp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toRightOf="#+id/reviewer_avatar"
app:layout_constraintTop_toBottomOf="#+id/reviewer_avatar"/>
I think I found the answer to child textview's text is clipped.
I change it:
<TextView
android:id="#+id/comment_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/large_text"
android:textSize="16sp"
app:layout_constraintLeft_toRightOf="#+id/reviewer_avatar"
app:layout_constraintTop_toBottomOf="#+id/reviewer_avatar"/>
to
<TextView
android:id="#+id/comment_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#string/large_text"
android:textSize="16sp"
app:layout_constraintLeft_toRightOf="#+id/reviewer_avatar"
app:layout_constraintTop_toBottomOf="#+id/reviewer_avatar"
app:layout_constraintRight_toRightOf="parent"/>
This would solve the problem !
But this way, TextView can't scalable,only fill width.
Finnaly, the better answer:
<TextView
android:id="#+id/comment_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#string/reviewer_name"
android:textSize="16sp"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintLeft_toLeftOf="#+id/reviewer_name"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/reviewer_avatar"
app:layout_constraintWidth_default="wrap"/>
layout_margin can't be shown correctly; - margins space is outside view's bounds. app:layout_constraintLeft_toRightOf="#+id/reviewer_avatar" means that reviewer_name is constrained to the right side of reviewer_avatar not including margins. Set android:layout_marginLeft="8dp" of reviewer_name, comment_floor and comment_content.
child textview's text is clipped. - width of the comment_content is equal to the width of your ConstraintLayout, but the comment_content is constrained to the right side of reviewer_avatar. Therefore the right side of the comment_content goes beyond the boundaries of the ConstraintLayout, i.e. is clipped. Set the specific width of the comment_content for different screen sizes.
I believe this is a resize bug that should be fixed in 1.1 beta 1 (see https://androidstudio.googleblog.com/2017/05/constraintlayout-110-beta-1-release.html to install it) -- please try it and see if that's it.

Categories

Resources