Google has announced a new layout called "ConstraintLayout" that's supposed to be the ultimate layout, that could replace all of the layouts while staying flat (without nested layouts) and have better performance.
Thing is, I barely see any tutorials for it that could help me on this matter, other than the video presented on Google IO.
What I am trying to do is, given that I have a vertically-centered LinearLayout within another layout - convert them both into a single ConstraintLayout.
After all, this is the purpose of this new layout...
The layout I wish to deal with looks like this:
Notice that the views in the center are only centered vertically, and that the 2 textViews are to the right of the ImageView, which is also centered vertically.
This all works well with RelativeLayout, which has the LinearLayout of the 2 TextViews, but I wish to know how to convert them into a single ConstraintLayout.
Here's a sample XML of what I've shown:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:minHeight="?attr/listPreferredItemHeightSmall"> <ImageView android:id="@+id/appIconImageView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_centerVertical="true" android:layout_marginEnd="4dp" android:layout_marginLeft="2dp" android:layout_marginRight="4dp" android:layout_marginStart="2dp" android:adjustViewBounds="true" android:src="@android:drawable/sym_def_app_icon" tools:ignore="ContentDescription"/> <LinearLayout android:id="@+id/appDetailsContainer" android:layout_width="0px" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_toEndOf="@+id/appIconImageView" android:layout_toLeftOf="@+id/overflowView" android:layout_toRightOf="@+id/appIconImageView" android:layout_toStartOf="@+id/overflowView" android:orientation="vertical"> <TextView android:id="@+id/appLabelTextView" android:layout_width="match_parent" android:layout_height="wrap_content" android:ellipsize="marquee" android:text="label" android:textAppearance="?android:attr/textAppearanceLarge" android:textDirection="locale" tools:ignore="HardcodedText,UnusedAttribute"/> <TextView android:id="@+id/appDescriptionTextView" android:layout_width="match_parent" android:layout_height="wrap_content" android:ellipsize="marquee" android:minLines="3" android:text="description" android:textAppearance="?android:attr/textAppearanceSmall" android:textDirection="locale" tools:ignore="HardcodedText,UnusedAttribute"/> </LinearLayout> <ImageView android:id="@+id/overflowView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentEnd="true" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:adjustViewBounds="true" android:background="?attr/selectableItemBackground" android:clickable="true" android:padding="10dp" app:srcCompat="@drawable/ic_more_vert_black_24dp" tools:src="@drawable/ic_more_vert_black_24dp" tools:ignore="ContentDescription"/> <ImageView android:id="@+id/isSystemAppImageView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignEnd="@+id/overflowView" android:layout_alignLeft="@+id/overflowView" android:layout_alignParentBottom="true" android:layout_alignRight="@+id/overflowView" android:layout_alignStart="@+id/overflowView" android:adjustViewBounds="true" android:scaleType="centerInside" app:srcCompat="@drawable/ic_warning_black_24dp" tools:ignore="ContentDescription" tools:src="@drawable/ic_warning_black_24dp"/> </RelativeLayout>
I tried to read some articles and watch some videos of Google :
That didn't help, so I tried to using it, hoping I will find out how to use it myself. But I can't find out how to do it. I tried using the feature to convert the layouts, but this makes a huge mess of the views and puts additional margins that I don't want to have.
How can I convert the 2 layouts into a single ConstraintLayout ?
Center a view horizontally, set layout_constraintLeft_toLeftOf and layout_constraintRight_toRightOf to parent. Center a view vertically, set layout_constraintTop_toTopOf and layout_constraintBottom_toBottomOf to parent. Align to the top left.
Creating a chain is really easy, we can click and drag to select views or press ctrl and select views from Component Tree. And then right click on selected views in Editor Or Component Tree to apply constraints. You can see that in action in following screen records.
ConstraintLayout has flat view hierarchy unlike other layouts, so does a better performance than relative layout. Yes, this is the biggest advantage of Constraint Layout, the only single layout can handle your UI. Where in the Relative layout you needed multiple nested layouts (LinearLayout + RelativeLayout).
ContraintLayout
contains a feature - Chains
- that makes it possible to implement what you are asking:
Chains provide group-like behavior in a single axis (horizontally or vertically).
A set of widgets are considered a chain if they a linked together via a bi-directional connection
Once a chain is created, there are two possibilities:
- Spread the elements in the available space
- A chain can also be "packed", in that case the elements are grouped together
As for your case, you'll have to pack your label
and description
TextViews and center them in you parent vertically:
(make sure you use a version of ConstraintLayout
that supports chains)
<?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"> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginTop="16dp" android:text="TextView" app:layout_constraintBottom_toTopOf="@+id/button" app:layout_constraintLeft_toRightOf="@+id/imageView2" app:layout_constraintTop_toTopOf="parent" app:layout_constraintHorizontal_chainStyle="packed"/> <TextView android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:text="Button\nMkay" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toRightOf="@+id/imageView2" app:layout_constraintTop_toBottomOf="@+id/textView"/> <ImageView android:id="@+id/imageView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginEnd="16dp" android:layout_marginTop="16dp" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:srcCompat="@mipmap/ic_launcher"/> <ImageView android:id="@+id/imageView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:layout_marginStart="16dp" android:layout_marginTop="16dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" app:srcCompat="@mipmap/ic_launcher"/> <ImageView android:id="@+id/imageView3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:layout_marginEnd="16dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintRight_toRightOf="parent" app:srcCompat="@mipmap/ic_launcher"/> </android.support.constraint.ConstraintLayout>
Now in constraint layout 1.1.3 we must use app:layout_constraintHorizontal_chainStyle="packed"
instead of app:layout_constraintVertical_chainPacked="true"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With