Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to center multiple Views together using ConstraintLayout?

Background

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.

The problem

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:

enter image description here

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> 

What I tried

I tried to read some articles and watch some videos of Google :

  • https://codelabs.developers.google.com/codelabs/constraint-layout/index.html#0
  • https://www.youtube.com/watch?v=sO9aX87hq9c
  • https://youtu.be/csaXml4xtN8?t=1693

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.

The question

How can I convert the 2 layouts into a single ConstraintLayout ?

like image 427
android developer Avatar asked May 29 '16 06:05

android developer


People also ask

How do I center a view in 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.

How do you use chain in ConstraintLayout?

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.

Is ConstraintLayout better than RelativeLayout?

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).


1 Answers

Take a look at my answer here.

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> 

Update 25-06-2019 (@Saeid Z):

Now in constraint layout 1.1.3 we must use app:layout_constraintHorizontal_chainStyle="packed" instead of app:layout_constraintVertical_chainPacked="true"

like image 113
Yury Fedorov Avatar answered Sep 18 '22 04:09

Yury Fedorov