314

With a Preview 1 of Android Studio 2.2 Google released a new layout in its support library: ConstraintLayout. With ConstraintLayout it is easier to use a Design tool in Android Studio, but I didn't find a way to use relative sizes (percents or 'weights' like in LinearLayout). Is there a way to define the constraints based on percents? E.g. make a View take 40% of a screen, create 20% margin between views, set a View's width to 50% of another View's width?

Zoe
  • 27,060
  • 21
  • 118
  • 148
Yury Fedorov
  • 14,508
  • 6
  • 50
  • 66
  • 5
    Percentage support for width or height was added in `version 1.1` of ConstraintLayout. See **"Percent dimension"** on https://developer.android.com/reference/android/support/constraint/ConstraintLayout or some of the newer answers. – sunadorer May 23 '18 at 15:27
  • the best solution without going into two much complications is the use of bias – Payel Senapati Mar 30 '21 at 07:49

14 Answers14

391

It may be useful to have a quick reference here.

Placement of views

Use a Guideline with app:layout_constraintGuide_percent like this:

<androidx.constraintlayout.widget.Guideline
    android:id="@+id/guideline"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:layout_constraintGuide_percent="0.5"/>

And then you can use this guideline as anchor points for other views.

or

Use bias with app:layout_constraintHorizontal_bias and/or app:layout_constraintVertical_bias to modify view location when the available space allows

<Button
    ...
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintHorizontal_bias="0.25"
    ...
    />

Size of views

Another percent based value is height and/or width of elements, with app:layout_constraintHeight_percent and/or app:layout_constraintWidth_percent:

<Button
    ...
    android:layout_width="0dp"
    app:layout_constraintWidth_percent="0.5"
    ...
    />

A useful addition to this is to set the other dimension relative to the first, for example - set the height according to the width, proportionally:

  app:layout_constraintDimensionRatio="1:1"
avianey
  • 5,545
  • 3
  • 37
  • 60
Amir Uval
  • 14,425
  • 4
  • 50
  • 74
  • 3
    why does it have width set to 1dp? – user924 Mar 01 '18 at 20:48
  • 1
    @user924 It would have made sense to give a guideline a width of 0dp, I don't know why the developers who implemented this decided on 1dp. Maybe because 0dp is regarded as "stretch" when using weights. – Amir Uval Mar 04 '18 at 09:25
  • 3
    @user924: `0dp` is used in ConstraintLayout to indicate dynamic sizing. See https://developer.android.com/reference/android/support/constraint/ConstraintLayout.html#DimensionConstraints – serv-inc Mar 05 '18 at 12:48
  • 1
    @serv-inc but here `1dp`, not `0dp`.. it's what I'm talking about – user924 Mar 05 '18 at 13:57
  • 3
    @user924: you need to set it to a width. `0dp` is already reserved, so `1dp` seems sensible. – serv-inc Mar 05 '18 at 14:26
  • but how to also make percent of some other view and not the parent? – user924 Nov 05 '21 at 09:33
  • @user924 - you can do that in code, override onMeasure() of the view you want to set size to, and you can give it the size of the other view. BTW - wow, you've just replied to an answer to a question you asked 3.5 years ago?? :) – Amir Uval Nov 08 '21 at 20:52
252

You can currently do this in a couple of ways.

One is to create guidelines (right-click the design area, then click add vertical/horizontal guideline). You can then click the guideline's "header" to change the positioning to be percentage based. Finally, you can constrain views to guidelines.

Another way is to position a view using bias (percentage) and to then anchor other views to that view.

That said, we have been thinking about how to offer percentage based dimensions. I can't make any promise but it's something we would like to add.

Marcel Bro
  • 4,907
  • 4
  • 43
  • 70
Romain Guy
  • 97,993
  • 18
  • 219
  • 200
  • 1
    0 down vote Could I ask a follow up? I'm trying to set an ImageView to be 60% width but maintain a 16:9 aspect ratio. I want the width to be fixed, but the height of the ImageView to be dynamic. Is that possible with ConstraintLayout? I'm struggling to get it to work - I end up with fixed width/height values of 0 unless I specify hardcoded dimensions. – MattWilliams89 Jun 07 '16 at 21:34
  • 3
    @MattWilliams89 There is a parameter called layout_constraintDimensionRatio, I guess it may be useful in your case, write "16:9" there. I didn't succeed trying to build your layout with it though, the image gets huge – Yury Fedorov Jun 08 '16 at 06:49
  • Yeah I'm setting the dimensionRatio to 16:9 which the image isn't constrained against another view (or Guideline) works fine. We want the two things to coexist. We're currently using PercentRelativeLayout but with the new changes to RecyclerView (wrap_content height etc), it doesn't work – MattWilliams89 Jun 08 '16 at 08:28
  • 1
    @RomainGuy how do you change positioning to be in percentage on guidlines's header?. i have tried to right click it and nothing shows up – Edijae Crusar Jul 08 '16 at 12:37
  • @RomainGuy ooh i got it, one only need to **click the header once** and it will change `app:relativeBegin` to `app:relativePercenge` – Edijae Crusar Jul 08 '16 at 12:46
  • 24
    To those wondering exactly what the guideline's header is, it's the circle that has an up or down arrow or a percentage symbol. Clicking that toggles between app:layout_constraintGuide_begin, app:layout_constraintGuide_end, and app:layout_constraintGuide_percent in XML. I encountered a small issue (on ConstraintLayout version 1.0.0-alpha8 where I had to click the guideline, hold down my mouse, and drag to the circle to toggle these in the editor, but I'm sure this bug will be fixed soon. – technoplato Sep 13 '16 at 22:12
  • @lustig still happening in v1.0.0-beta4 of the library – StuStirling Dec 09 '16 at 10:53
  • 4
    You can also set this in the XML of the layout using `app:layout_constraintGuide_percentage` – mez.pahlan Aug 08 '17 at 11:40
  • For anyone that wants percentage based view, You can just add 2 guides that have position set as percentage of the parent and you just anchor your view between them and set the desired ratio. This will result in having a view take up x percentage of the parent, x being guide2_percentage - guide_one percentage. – Mihai Mar 31 '18 at 15:56
  • I changed the view to show only the blueprint and the option become available. Just toggle off the Show design option. Hope it works for you !!! – newITguy Aug 07 '18 at 18:04
  • 1
    I created a picture to show what exactly a `header` is. Please reference this https://imgur.com/oFgwofk Or you just add this instruction in text mode: `app:layout_constraintGuide_percent` – Alston May 30 '19 at 08:00
  • The layout_constraintGuide_percentage isn't a percent. Percent means per 100. – Mitch May 28 '20 at 04:25
150

As of "ConstraintLayout1.1.0-beta1" you can use percent to define widths & heights.

android:layout_width="0dp"
app:layout_constraintWidth_default="percent"
app:layout_constraintWidth_percent=".4"

This will define the width to be 40% of the width of the screen. A combination of this and guidelines in percent allows you to create any percent-based layout you want.

naXa stands with Ukraine
  • 35,493
  • 19
  • 190
  • 259
hoford
  • 4,918
  • 2
  • 19
  • 19
  • 6
    In constraint layout 1.0.2 the **percent** value for **layout_constraintWidth_default** is not supported. I think the right way is to use the Guideline. – vovahost Jul 29 '17 at 15:59
  • 1
    it's working with Android Studio 3.0 built on October 20, 2017 – douarbou Nov 17 '17 at 16:30
  • 5
    As stated in the answer this was added in `version 1.1` of ConstraintLayout. The additional `_default="percent"` is not needed anymore on the stable version! See **"Percent dimension"** on https://developer.android.com/reference/android/support/constraint/ConstraintLayout – sunadorer May 23 '18 at 15:30
  • @hoford, for a View containing text, whose size is to be defined in `sp` units, how could text-size be auto-proportional to view's size (which is, by itself, defined proportionally to layout's total size, i.e. in 'percent')? – Bliss Feb 13 '19 at 18:16
  • @Bliss, textSize should be changed programmatically when a view changes it's size. – CoolMind Jan 25 '22 at 07:54
96

With the new release of ConstraintLayout v1.1 you can now do the following:

<Button
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintHeight_percent="0.2"
app:layout_constraintWidth_percent="0.65" />

This will constrain the button to be 20% the height and 65% of the width of the parent view.

amram99
  • 699
  • 8
  • 19
Adam
  • 2,845
  • 2
  • 32
  • 46
  • 2
    for me worked only when I changed from "android:" to "app:" -> app:layout_constraintHeight_percent="0.2" – Kirill Karmazin May 16 '18 at 20:27
  • This is a must for me when following the fluid layout of material design. https://material.io/design/layout/component-behavior.html#component-width –  May 19 '18 at 17:58
  • @Adam, for a View containing text, whose size is to be defined in `sp` units, how could text-size be auto-proportional to view's size (which is, by itself, defined proportionally to layout's total size, i.e. in 'percent')? – Bliss Feb 13 '19 at 18:17
  • 1
    @Bliss Sounds like this could help: https://developer.android.com/guide/topics/ui/look-and-feel/autosizing-textview I have never used it myself though. – Adam Feb 14 '19 at 08:25
47

How to use Guidelines

The accepted answer is a little unclear about how to use guidelines and what the "header" is.

Steps

First add a Guideline.

enter image description here

Select the Guidline or move it a little bit to make the constraints visible.

enter image description here

Then click the round circle (the "header") until it becomes a percent. You can then drag this percentage down to 50% or whatever you want.

enter image description here

After that you can constrain your view to the Guideline to make it some percentage of the parent (using match_constraint on the view).

enter image description here

Community
  • 1
  • 1
Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
  • Where should the 'header' be visible? It doesn't show up in my view. – Marcel50506 Nov 10 '17 at 11:23
  • @Marcel50506, make sure that both the Design and Blueprint views are showing. That will give you the best chance at being able to see it. If you can see the guideline line, try clicking on it to select it. If you can't see the line, then try clicking on the guideline item in the Component Tree menu that should be off to the left side (assuming you added a guideline already). – Suragch Nov 10 '17 at 11:56
  • 1
    I don't see the circle, but when clicking on the left of the guideline I can alter it to percentages.. Render issue I think. Thank you. – Marcel50506 Nov 13 '17 at 08:38
  • This is the best answer because it proposes better layout approach. We can align multiple views on the base-guideline instead of adding percentage on only one view – Nguyen Minh Hien May 27 '19 at 09:04
37

The Guideline is invaluable - and the app:layout_constraintGuide_percent is a great friend... However sometimes we want percentages without guidelines. Now it's possible to use weights:

android:layout_width="0dp"
app:layout_constraintHorizontal_weight="1"

Here is a more complete example that uses a guideline with additional weights:

<?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"
    android:padding="16dp"
    tools:context="android.itomerbu.layoutdemo.MainActivity">

    <android.support.constraint.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.44"/>

    <Button
        android:id="@+id/btnThird"
        android:layout_width="0dp"
        app:layout_constraintHorizontal_weight="1"
        android:layout_height="wrap_content"
        android:text="@string/btnThird"
        app:layout_constraintLeft_toLeftOf="parent"
        android:layout_marginBottom="8dp"
        app:layout_constraintRight_toLeftOf="@+id/btnTwoThirds"
        app:layout_constraintBottom_toTopOf="@+id/guideline"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"/>

    <Button
        android:id="@+id/btnTwoThirds"
        app:layout_constraintHorizontal_weight="2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="@string/btnTwoThirds"
        app:layout_constraintBottom_toBottomOf="@+id/btnThird"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toRightOf="@+id/btnThird"/>
</android.support.constraint.ConstraintLayout>
TomerBu
  • 1,483
  • 15
  • 15
  • 2
    @Plumbus - Weights are equivalent to percentages (any percent can be mathematically converted to a weight and vice-versa). By being nit-picky on terminology you miss the point of the answer. – SMBiggs May 23 '18 at 15:40
32

Constraint Layout 1.0 making a view take up a percentage of the screen required making two guidelines. In Constraint Layout 1.1 it’s been made simpler by allowing you to easily constrain any view to a percentage width or height.

enter image description here

Isn’t this fantastic? All views support layout_constraintWidth_percent and layout_constraintHeight_percent attributes. These will cause the constraint to be fixed at a percentage of the available space. So making a Button or a TextView expand to fill a percent of the screen can be done with a few lines of XML.

For example, if you want to set the width of the button to 70% of screen, you can do it like this:

<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_constraintWidth_percent="0.7" />

Please note that you will have to put the dimension should be used as percentage to 0dp as we have specified android:layout_width to 0dp above.

Similarly, if you want to set the height of the button to 20% of screen, you can do it like this:

<Button
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_constraintHeight_percent="0.2" />

See! we have specified android:layout_height to 0dp this time as we want button to use height as percentage.

Ashish Satpute
  • 755
  • 1
  • 8
  • 9
13

With the ConstraintLayout v1.1.2, the dimension should be set to 0dp and then set the layout_constraintWidth_percent or layout_constraintHeight_percent attributes to a value between 0 and 1 like :

<!-- 50% width centered Button -->
<Button
    android:id="@+id/button"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintWidth_percent=".5" />

(You don't need to set app:layout_constraintWidth_default="percent" or app:layout_constraintHeight_default="percent" with ConstraintLayout 1.1.2 and following versions)

Bubu
  • 1,533
  • 14
  • 14
11

Try this code. You can change the height and width percentages with app:layout_constraintHeight_percent and app:layout_constraintWidth_percent.

<?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">

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#FF00FF"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHeight_percent=".6"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintWidth_percent=".4"></LinearLayout>

</android.support.constraint.ConstraintLayout>

Gradle:

dependencies {
...
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
}

enter image description here

live-love
  • 48,840
  • 22
  • 240
  • 204
7

you can use app:layout_constraintVertical_weight it same as layout_weight in linearlayout

<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">

<Button
    android:id="@+id/button4"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:text="Button"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toLeftOf="@+id/button5"
    app:layout_constraintVertical_weight="1"/>

<Button
    android:id="@+id/button5"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:text="Button"
    app:layout_constraintLeft_toRightOf="@+id/button4"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintVertical_weight="1"/>
</android.support.constraint.ConstraintLayout>

NOTE: app:layout_constraintVertical_weight(app:layout_constraintHorizontal_weight) will work with android:layout_width="0dp" (android:layout_height="0dp"

vuhung3990
  • 6,353
  • 1
  • 45
  • 44
6

For someone that might find useful, you can use layout_constraintDimensionRatio im any child view inside a ConstraintLayout and we can define the Height or Width a ratio of the other dimension( at least one must be 0dp either width or heigh) example

 <ImageView
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:src="@drawable/top_image"
        app:layout_constraintDimensionRatio="16:9"        
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"/>

in this case the aspect ratio it's 16:9 app:layout_constraintDimensionRatio="16:9" you can find more info HERE

Vasily Kabunov
  • 6,511
  • 13
  • 49
  • 53
Javier
  • 1,469
  • 2
  • 20
  • 38
6

Using Guidelines you can change the positioning to be percentage based

<android.support.constraint.Guideline
android:id="@+id/guideline"
android:layout_width="1dp"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5"/>

You can also use this way

android:layout_width="0dp"
app:layout_constraintWidth_default="percent"
app:layout_constraintWidth_percent="0.4"
Ashish Satpute
  • 755
  • 1
  • 8
  • 9
3

I know this isn't directly what OP was originally asking for but this helped me a lot in this situation when I had a similar question.. Adding this for people looking to change the layout window size (which i use regularly), via code. Add this to your onCreate in the activity of question. (Changes it to 80%)

DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);

int width = dm.widthPixels;
int height = dm.heightPixels;

getWindow().setLayout((int)(width * 0.8), (int)(height * 0.8));
ProgAz
  • 83
  • 5
2

Simply, just replace , in your guideline tag

app:layout_constraintGuide_begin="291dp"

with

app:layout_constraintGuide_percent="0.7"

where 0.7 means 70%.

Also if you now try to drag guidelines, the dragged value will now show up in %age.

Udit Kapahi
  • 2,277
  • 1
  • 27
  • 25