Want I want to achieve is to compose two views, where one has some fixed aspect ratio and the other one stays below the first (unless the first gives enough space for the second one).
Here is one case:
Here is second case:
These two views are placed inside ConstraintLayout. I tried to use this part of code:
<?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">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/view1"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="0.75"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/view2"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintHeight_min="100dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/view1"/>
</androidx.constraintlayout.widget.ConstraintLayout>
But it works only in the first case where there is enough space for View 2. In the second case, View 2 is moved below View 1 and it's outside the screen.
Edit
I've found solution, which I'm not proud of it, but it works. Still waiting for better idea. How it works? I put additional view (placeholder) which doesn't have constrained width to MATCH_PARENT but it has bottom margin (simulating minimum height for View 2). Placeholder behaves in the same way like View 1 when there is more space than minimum height, but in other cases it narrows a little bit to leave bottom margin.
<?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"
android:background="#android:color/black">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/view1"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintDimensionRatio="0.75"
app:layout_constraintTop_toTopOf="parent"/>
<View
android:id="#+id/placeholder"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="100dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintDimensionRatio="0.75"
app:layout_constraintVertical_bias="0"
app:layout_constraintBottom_toBottomOf="parent"/>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/view2"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="#id/placeholder"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Well for starters, I don't see you trying to add any constraint to the dimensions of the first view. If you want it to have a fixed aspect ratio of 3:4 you should set app:layout_constraintDimensionRatio="H,3:4" to your desired view and remove the app:layout_constraintDimensionRatio="0.75". Therefore you won't need the placeholder view any longer. So your layout would look something like this:
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/view1"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="H,3:4"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/view2"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/view1" />
But if you wish to keep your view1 heigh to a 75% screen ratio, then you should replace your placeholder view with a horizontal Guideline to which you set your app:layout_constraintGuide_percent="0.75". So the layout would look like this:
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/view1"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="#id/guideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.75" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/view2"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/view1" />
Also please keep in mind that using match_parent inside a ConstraintLayout is not recommended. Instead, use the 0dp height/width dimension and set the appropriate constraint for the margins depending on the case (top, bottom / start, end)
Related
I canĀ“t understand constraints behaviour. Take a look to this layout
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="#+id/button"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#color/purple_200"
android:text="whatever"
app:layout_constraintDimensionRatio="w, 1:1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
It is supposed 0dp mean all available space. This button has both dimensions 0dp and a 1:1 ratio. And it is aligned left and top with parent so I guess it will be showing a square with a parent width as a side. But it is showing something unexpected for me, just a point on the upper left corner (even it is having some text):
It is clear I am not understanding this layout properly. Please enlighten me
You need to add to more constraints in order to work
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
If you are using 0dp for height, you need to constraint both top and bottom and vice versa
Copy and past this
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="#+id/btn"
android:layout_width="126dp"
android:layout_height="53dp"
android:text="Button"
android:textSize="20sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
i think you need to add more Constraint!
add this :
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
for this case, it will must like this :
<Button
android:id="#+id/button"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#color/purple_200"
android:text="whatever"
app:layout_constraintDimensionRatio="w, 1:1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
hope this help you, have a great day! don't forget to take coffe time!
Stay Coding and Stay Awesome!
Say, I have 2 View: A and B. A's size is set to wrap_content, causing its size might change when content varies: text size, image size, data amounts... etc.
I want View B's height/width related to View A's, but by ratio ---- for example, B's height is 1/3 of A's. How can I achieve it?
As far as I know, ConstraintLayout should come to rescue. But I could only make it
equals by setting constraintTop_toTopOf="#+id/viewA" and app:layout_constraintBottom_toBottomOf="#+id/viewA". I tried using Guideline to locate the "dedicated height" -- but it seems Guideline is only related to parent (not constraint).
TL;DR
My solution so far is: combined layout_constraintHeight_percent (or layout_constraintWidth_percent) with a ConstraintLayout wrapper.
Limit of "Percent"
I went around asking people. Some say that layout_constraintHeight_percent (or layout_constraintWidth_percent) should be used in this case:
<?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">
<TextView
android:id="#+id/baseA"
android:layout_width="100dp"
android:layout_height="300dp"
android:background="#color/teal_200"
android:gravity="center"
android:text="base A"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:layout_width="100dp"
android:layout_height="0dp"
android:background="#color/purple_200"
android:gravity="center"
android:text="base B"
app:layout_constraintBottom_toBottomOf="#+id/baseA"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.7"
app:layout_constraintHeight_percent="0.33"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/baseA" />
</androidx.constraintlayout.widget.ConstraintLayout>
However, layout_constraintHeight_percent encountered the same problem as Guideline: they are calculated according to parent's size, no matter what constraint they have:
Some say layout_constrainedHeight should set to true, but nothing changed:
Adaption: B-specified Wrapper
Above behavior gave me an idea: since constraint percent is only calculated by parent, then we could modify the parent -- by giving it a custom one.
Change above code, take view B to a new ConstraintLayout, migrate B into it, constraint to parent, and use percent again:
<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">
<TextView
android:id="#+id/baseA"
android:layout_width="100dp"
android:layout_height="300dp"
android:background="#color/teal_200"
android:gravity="center"
android:text="base A"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="#+id/baseA"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.7"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/baseA">
<TextView
android:layout_width="100dp"
android:layout_height="0dp"
android:background="#color/purple_200"
android:gravity="center"
android:text="base B"
app:layout_constrainedHeight="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent="0.33"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Now it works like a charm.
Better Approach: Inside Same Wrapper
Another solution is to put A and B inside the same ConstraintLayout, and set its height/width to wrap_content, causing its size to equal to A:
<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">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="#+id/baseA"
android:layout_width="100dp"
android:layout_height="300dp"
android:background="#color/teal_200"
android:gravity="center"
android:text="base A"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:layout_width="100dp"
android:layout_height="0dp"
android:background="#color/purple_200"
android:gravity="center"
android:text="base B"
app:layout_constrainedHeight="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.7"
app:layout_constraintHeight_percent="0.33"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
And I think it's a better solution -- because in only-B-wrapper solution, you cannot set padding in that wrapper ConstraintLayout, as layout_constraintHeight_percent only calculated size inside (it ignores padding and margin). But in above share-wrapper solution, you can set a padding without worry (as they share the same parent size).
I've got ConstraintLayout which contains TextView and includes other ConstraintLayout. The reason why I include other constraint is that in this project I'm using an old version of support library(26.1.0) which doesn't contain groups and currently I'm not able to upgrade it.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/topTitleTextView"
style="#style/TextBigMinus"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/margin_normal"
android:layout_marginRight="#dimen/margin_normal"
android:layout_marginBottom="#dimen/margin_normal"
android:gravity="center_horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
<include
android:id="#+id/included_part"
layout="#layout/included_part"
android:layout_height="0dp"
android:layout_width="0dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#id/topTitleTextView"
app:layout_constraintBottom_toBottomOf="parent"/>
</android.support.constraint.ConstraintLayout>
I'm setting my text straight from the code and on different devices, it can have one or two lines. When it has two lines, the included part will be moved by the height of the line but should be resized as it has an app:layout_constraintBottom_toBottomOf="parent".
What causes that and how it could be fixed?
try to remove app:layout_constraintBottom_toBottomOf="parent"
and set android:layout_height="wrap_content"
This should work fine as per your requirement
<android.support.constraint.ConstraintLayout xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/topTitleTextView"
android:layout_width="0dp"
android:layout_height="0dp"
android:gravity="center_horizontal"
app:layout_constraintBottom_toTopOf="#+id/included_part"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
<include
android:id="#+id/included_part"
layout="#layout/included_part"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/topTitleTextView"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
Since you want the included part to move as the height of the text line changes also get resized to fit in the available screen, having the app:layout_constraintBottom_toBottomOf="parent" won't work on layouts that include views (TextView, ImageView etc), nested included layouts with fixed height values in dp or sp unit. Make sure the included view has every height attribute set to 0dp inside ConstraintLayout and then use this code where I've fixed the constraint fields:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/topTitleTextView"
style="#style/TextBigMinus"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/margin_normal"
android:layout_marginRight="#dimen/margin_normal"
android:layout_marginBottom="#dimen/margin_normal"
android:gravity="center_horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
<include
android:id="#+id/included_part"
layout="#layout/included_part"
android:layout_height="0dp"
android:layout_width="0dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#id/topTitleTextView"
app:layout_constraintBottom_toBottomOf="parent"/>
</android.support.constraint.ConstraintLayout>
The text view bottom is constraint to parent, while the included part bottom also constraint to parent. This will resulted of some part of the view overlap each other. Try to remove app:layout_constraintBottom_toBottomOf="parent" on the text view property.
I am having an issue with ConstraintLayout and a specific view.
What is wanted : 3 imageviews in a 6:5 ratio, the first one is bigger with the two other stacked vertically on its right. The whole view has a maxed width of 414dp.
When trying to set the horizontal chain style at packed, the views don't display at all over 414dp.
There is no issue under that limit or with a chain style other than packed.
Here are
the layout :https://gist.github.com/xcaEi/ba46e5e8c2d1d5682e1a5f3221325ed0
screenshots of the problem : https://imgur.com/a/0uZckj0
Am I missing something ?
To achieve what you want, I believe you must nest a ConstraintLayout inside another ConstraintLayout.
The problem is that you can't have both app:layout_constraintWidth_percent and layout_constraintWidth_max defined on the same view; each of these is one option for how to constrain a view set to "match constraints".
MATCH_CONSTRAINT dimensions (Added in 1.1)
When a dimension is set to MATCH_CONSTRAINT, the default behavior is to have the resulting size take all the available space. Several additional modifiers are available:
layout_constraintWidth_min and layout_constraintHeight_min: will set the minimum size for this dimension
layout_constraintWidth_max and layout_constraintHeight_max: will set the maximum size for this dimension
layout_constraintWidth_percent and layout_constraintHeight_percent: will set the size of this dimension as a percentage of the parent
(From https://developer.android.com/reference/android/support/constraint/ConstraintLayout)
You can work around this by having your inner ConstraintLayout specify its maximum width, and then have the ImageView children of that inner ConstrainLayout specify their percentages.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.constraint.ConstraintLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#eee"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintWidth_max="414dp">
<ImageView
android:id="#+id/main_imageview"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="fitXY"
android:background="#caf"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintDimensionRatio="H,6:5"
app:layout_constraintWidth_percent="0.666"/>
<ImageView
android:id="#+id/second_imageview"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="fitXY"
android:background="#fac"
app:layout_constraintTop_toTopOf="#+id/main_imageview"
app:layout_constraintLeft_toRightOf="#+id/main_imageview"
app:layout_constraintBottom_toTopOf="#+id/third_imageview"
app:layout_constraintDimensionRatio="W,6:5"/>
<ImageView
android:id="#+id/third_imageview"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="fitXY"
android:background="#afc"
app:layout_constraintTop_toBottomOf="#+id/second_imageview"
app:layout_constraintLeft_toRightOf="#+id/main_imageview"
app:layout_constraintBottom_toBottomOf="#+id/main_imageview"
app:layout_constraintDimensionRatio="W,6:5"/>
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
I think this is your need 3 imageview first one bigger. You can change layout_constraintHorizontal_weight properties check below
<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">
<ImageView
android:id="#+id/imageView9"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#android:color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="6:5"
app:layout_constraintEnd_toStartOf="#+id/imageView10"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintHorizontal_weight="2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="#+id/imageView10"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#android:color/darker_gray"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="6:5"
app:layout_constraintEnd_toStartOf="#+id/imageView11"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="#+id/imageView9"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="#+id/imageView11"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#android:color/holo_orange_dark"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="6:5"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="#+id/imageView10"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
This layout will display a View with a color and another with another color.
When layout_constraintWidth_percent = 1 the views are the same width. When I set it between 0.92 <> 1 the foreground view becomes bigger then the background.
Can anyone solve this? I need the foreground to be x percentage of the background
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="15dp"
android:paddingBottom="15dp"
>
<View
android:id="#+id/background"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_marginEnd="16dp"
android:layout_marginStart="16dp"
android:background="#color/colorPrimary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<View
android:id="#+id/foreground"
android:layout_width="0dp"
android:layout_height="80dp"
android:background="#color/colorAccent"
app:layout_constraintWidth_percent="0.94"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintBottom_toBottomOf="#id/background"
app:layout_constraintLeft_toLeftOf="#id/background"
app:layout_constraintRight_toRightOf="#id/background"
app:layout_constraintTop_toTopOf="#id/background"
/>
</android.support.constraint.ConstraintLayout>
Remove the start and end margins of the background. If you want left and right margins, put them on the parent ConstraintLayout instead. As it is now you have margins on background but not on foreground.
Also set the background width to 0dp (the same as foreground). This way the background will be the full width of the parent ConstraintLayout (which can itself apply the margins you want) and the foreground will be the specified percentage of the background. Also set the horizontal bias of the foreground to 0.5 if you want it to be centered.
Like this
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="15dp"
android:paddingBottom="15dp"
android:layout_marginEnd="16dp"
android:layout_marginStart="16dp"
>
<View
android:id="#+id/background"
android:layout_width="0dp"
android:layout_height="100dp"
android:background="#color/colorPrimary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<View
android:id="#+id/foreground"
android:layout_width="0dp"
android:layout_height="80dp"
android:background="#color/colorAccent"
app:layout_constraintWidth_percent="0.94"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintBottom_toBottomOf="#id/background"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="#id/background"
/>
</android.support.constraint.ConstraintLayout>
As stated from the doc, the percentage is relative to the parent:
When a dimension is set to MATCH_CONSTRAINT, the default behavior is
to have the resulting size take all the available space. Several
additional modifiers are available:
layout_constraintWidth_min and layout_constraintHeight_min : will set
the minimum size for this dimension
layout_constraintWidth_max and
layout_constraintHeight_max : will set the maximum size for this
dimension
layout_constraintWidth_percent and
layout_constraintHeight_percent : will set the size of this dimension
as a percentage of the parent
The app:layout_constraintWidth_percent attribute is calculated according to the parent ConstraintLayout's dimension and not the horizontal constraints of the View. So you need to wrap the foreground in another ConstraintLayout like this (which is a bit ugly because of the nested layout):
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="15dp"
android:paddingBottom="15dp">
<View
android:id="#+id/background"
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_marginEnd="16dp"
android:layout_marginStart="16dp"
android:background="#color/colorPrimary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<android.support.constraint.ConstraintLayout
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="#id/background"
app:layout_constraintLeft_toLeftOf="#id/background"
app:layout_constraintRight_toRightOf="#id/background"
app:layout_constraintTop_toTopOf="#id/background">
<View
android:id="#+id/foreground"
android:layout_width="0dp"
android:layout_height="80dp"
android:background="#color/colorAccent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintWidth_percent="0.94"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
Keep in mind that using app:layout_constraintWidth_percent and margins on a View at the same time can potentially lead to some problems because the margins aren't taken into account for the width percentage.
You can also consider removing the margins from the background and possibly adding them to root ConstraintLayout as padding and I think this would help avoid having a nested layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="15dp"
android:paddingBottom="15dp"
android:paddingStart="16dp"
android:paddingEnd="16dp">
<View
android:id="#+id/background"
android:layout_width="0dp"
android:layout_height="100dp"
android:background="#color/colorPrimary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<View
android:id="#+id/foreground"
android:layout_width="0dp"
android:layout_height="80dp"
android:background="#color/colorAccent"
app:layout_constraintWidth_percent="0.94"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintBottom_toBottomOf="#id/background"
app:layout_constraintLeft_toLeftOf="#id/background"
app:layout_constraintRight_toRightOf="#id/background"
app:layout_constraintTop_toTopOf="#id/background"/>
</android.support.constraint.ConstraintLayout>