A common use for LinearLayout is to evenly space (weight) views, for example:
How do you implement evenly spaced views like this using the new ConstraintLayou
Well if it helps someone
the key is here app:layout_constraintHorizontal_weight="1"
and
the best thing about constraint layout is that it supports circular dependency and here this is what I have done using exactly that.
For first child
app:layout_constraintEnd_toStartOf="@+id/textInputSecondChild"
For second child
app:layout_constraintLeft_toRightOf="@+id/textInputFirstChild"
here is the complete demo
<android.support.design.widget.TextInputLayout
android:id="@+id/textInputParent"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
<EditText
android:id="@+id/editTextParent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/state" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/textInputFirstChild"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toStartOf="@+id/textInputSecondChild"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textInputParent">
<EditText
android:id="@+id/editTextChildOne"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/pin_code" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/textInputSecondChild"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintLeft_toRightOf="@+id/textInputFirstChild"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textInputParent">
<EditText
android:id="@+id/editTextChildSecond"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/country" />
</android.support.design.widget.TextInputLayout>
To create 2 views in same line, equal width, just need to define
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<Button
android:id="@+id/button1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button 1"
app:layout_constraintEnd_toStartOf="@+id/button2"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/button2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button 2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/button1" />
</android.support.constraint.ConstraintLayout>
Note
MATCH_CONSTRAINT
)button1
and button2
must like aboveResult
MORE
If you want View1
bigger than View2
you can use weight
or percent
.
Example, View1
width = 2 *View2
width use weight
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<Button
android:id="@+id/button3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button 3"
app:layout_constraintEnd_toStartOf="@+id/button4"
app:layout_constraintHorizontal_weight="2"
app:layout_constraintStart_toStartOf="parent"
/>
<Button
android:id="@+id/button4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button 4"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="@+id/button3"
/>
</android.support.constraint.ConstraintLayout>
Result
Example, View1
width = 2 *View2
width use percent
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<Button
android:id="@+id/button5"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button 5"
app:layout_constraintEnd_toStartOf="@+id/button6"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintWidth_percent="0.667"
/>
<Button
android:id="@+id/button6"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button 6"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/button5"
app:layout_constraintWidth_percent="0.333"
/>
</android.support.constraint.ConstraintLayout>
Result
Once you have your chained items, you can still use weights on them like relative layout to keep them evenly spaced. The example below shows how to keep them evenly spaced with different size textViews.
<TextView1
app:layout_constraintHorizontal_weight="1" />
<TextView2
app:layout_constraintHorizontal_weight="1" />
<TextView3
app:layout_constraintHorizontal_weight="1" />
<TextView4
app:layout_constraintHorizontal_weight="1" />
There are two ways to accomplish this using ConstraintLayout
: Chains and Guidelines. To use Chains, make sure you are using ConstraintLayout
Beta 3 or newer and if you want to use the visual layout editor in Android Studio, make sure you are using Android Studio 2.3 Beta 1 or newer.
Method 1 - Using Chains
Open the layout editor and add your widgets as normal, adding parent constraints as needed. In this case, I have added two buttons with constraints to the bottom of the parent and side of the parent (left side for Save button and right side for Share button):
Note that in this state, if I flip to landscape view, the views do not fill the parent but are anchored to the corners:
Highlight both views, either by Ctrl/Cmd clicking or by dragging a box around the views:
Then right-click on the views and choose "Center Horizontally":
This sets up a bi-directional connection between the views (which is how a Chain is defined). By default the chain style is "spread", which is applied even when no XML attribute is included. Sticking with this chain style but setting the width of our views to 0dp
lets the views fill the available space, spreading evenly across the parent:
This is more noticeable in landscape view:
If you prefer to skip the layout editor, the resulting XML will look like:
<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">
<Button
android:id="@+id/button_save"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/button_save_text"
android:layout_marginStart="8dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="4dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toLeftOf="@+id/button_share"
app:layout_constraintHorizontal_chainStyle="spread" />
<Button
android:id="@+id/button_share"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/button_share_text"
android:layout_marginStart="4dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintLeft_toRightOf="@+id/button_save"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</android.support.constraint.ConstraintLayout>
Details:
0dp
or MATCH_CONSTRAINT
lets the views fill the parent (optional)layout_constraintHorizontal_chainStyle
, see the documentation for various chain styles, if the chain style is omitted, the default is "spread"layout_constraintHorizontal_weight
Method 2 - Using a Guideline
Open your layout in the editor and click the guideline button:
Then select "Add Vertical Guideline":
A new guideline will appear, that by default, will likely be anchored to the left in relative values (denoted by left-facing arrow):
Click the left-facing arrow to switch it to a percentage value, then drag the guideline to the 50% mark:
The guideline can now be used as an anchor for other views. In my example, I attached the right of the save button and the left of the share button to the guideline:
If you want the views to fill up the available space then the constraint should be set to "Any Size" (the squiggly lines running horizontally):
(This is the same as setting the layout_width
to 0dp
).
A guideline can also be created in XML quite easily rather than using the layout editor:
<android.support.constraint.Guideline
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/guideline"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
You shoul read about weighted chains. An example of code is here.
<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"
>
<TextView
android:id="@+id/figure_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
app:layout_constraintEnd_toStartOf="@id/figure_2"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toStartOf="parent"
tools:text="1"
/>
<TextView
android:id="@+id/figure_2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
app:layout_constraintEnd_toStartOf="@id/figure_3"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="@id/figure_1"
tools:text="2"
/>
<TextView
android:id="@+id/figure_3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
app:layout_constraintEnd_toStartOf="@id/figure_4"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="@id/figure_2"
tools:text="3"
/>
<TextView
android:id="@+id/figure_4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="@id/figure_3"
tools:text="4"
/>
</android.support.constraint.ConstraintLayout>
So, set android:layout_width="0dp"
, app:layout_constraintHorizontal_weight="1"
and link every view with neighbours like:
app:layout_constraintStart_toEndOf="@id/figure_2"
app:layout_constraintEnd_toStartOf="@id/figure_4"