1

I would like to add 3 buttons into my Android ConstraintLayout such that they are spanned horizontally. I thought that this can be done by using chains. So I made a chain out of them and then expanded their view (by marking them --> Right Click --> Organize --> Expand Horizontally). However this just expands them for one specific device. When switching to another device the buttons don't look correct any more. Here is my 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"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/outerConstraintLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/rigthInnerConstraintLayout"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@color/white"
        app:layout_constraintBottom_toBottomOf="@+id/outerConstraintLayout"
        app:layout_constraintEnd_toEndOf="@+id/outerConstraintLayout"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintStart_toStartOf="@+id/outerConstraintLayout"

        app:layout_constraintTop_toTopOf="@+id/outerConstraintLayout"
        app:layout_constraintVertical_bias="1.0">

        <Button
            android:id="@+id/button_1"
            android:layout_width="425dp"
            android:layout_height="@dimen/_30sdp"
            android:text="Button 1"
            app:layout_constraintEnd_toStartOf="@+id/button_2"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <Button
            android:id="@+id/button_2"
            android:layout_width="425dp"
            android:layout_height="@dimen/_30sdp"
            android:text="Button 2"
            app:layout_constraintEnd_toStartOf="@+id/button_3"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/button_1"
            app:layout_constraintTop_toTopOf="parent" />

        <Button
            android:id="@+id/button_3"
            android:layout_width="426dp"
            android:layout_height="@dimen/_30sdp"
            android:text="Button_3"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/button_2"
            app:layout_constraintTop_toTopOf="parent" />
    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

For the height I use scalable I use scalable size units (https://github.com/intuit/sdp) but for the width of the buttons dp values are assigned by Android Studio (after the expanding). I think that this is the problem. These dp values are hard coded. This means when changing the device the values are still the same which leads to the not correct look. My question is how can I arrange the 3 buttons in a chain (or whatever) such that they span over a whole row horizontally for any device?

Tamir Abutbul
  • 7,301
  • 7
  • 25
  • 53
VanessaF
  • 515
  • 11
  • 36

2 Answers2

2

These dp values are hard coded. This means when changing the device the values are still the same which leads to the not correct look - this is correct.

How to fix

If you will replace android:layout_width="426dp" on your buttons with android:layout_width="0dp".
your buttons will now resect the constraints and now every button will take 33.3% of the screen width.

You can change the width that every button will take by adding app:layout_constraintWidth_percent="0.x" to your button (it will only work if your view will have android:layout_width="0dp" as well), now your button will take x% of the screen width.

Example

For a 3 buttons places In a row but the center button will take 50% of the screen size you can use it like this:

<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:id="@+id/outerConstraintLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

 <androidx.constraintlayout.widget.ConstraintLayout
     android:id="@+id/rigthInnerConstraintLayout"
     android:layout_width="0dp"
     android:layout_height="0dp"
     android:background="@color/white"
     app:layout_constraintBottom_toBottomOf="@+id/outerConstraintLayout"
     app:layout_constraintEnd_toEndOf="@+id/outerConstraintLayout"
     app:layout_constraintHorizontal_bias="1.0"
     app:layout_constraintStart_toStartOf="@+id/outerConstraintLayout"

     app:layout_constraintTop_toTopOf="@+id/outerConstraintLayout"
     app:layout_constraintVertical_bias="1.0">

  <Button
      android:id="@+id/button_1"
      android:layout_width="0dp"
      android:layout_height="50dp"
      android:text="Button 1"
      app:layout_constraintEnd_toStartOf="@+id/button_2"
      app:layout_constraintHorizontal_bias="0.5"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toTopOf="parent" />

  <Button
      android:id="@+id/button_2"
      android:layout_width="0dp"
      app:layout_constraintWidth_percent="0.5"
      android:layout_height="50dp"
      android:text="Button 2"
      app:layout_constraintEnd_toStartOf="@+id/button_3"
      app:layout_constraintHorizontal_bias="0.5"
      app:layout_constraintStart_toEndOf="@+id/button_1"
      app:layout_constraintTop_toTopOf="parent" />

  <Button
      android:id="@+id/button_3"
      android:layout_width="0dp"
      android:layout_height="50dp"
      android:text="Button_3"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintHorizontal_bias="0.5"
      app:layout_constraintStart_toEndOf="@+id/button_2"
      app:layout_constraintTop_toTopOf="parent" />
 </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

And it will look like this:

enter image description here

Without app:layout_constraintWidth_percent="0.5" every button will take equal space and it will look like this:

enter image description here

Tamir Abutbul
  • 7,301
  • 7
  • 25
  • 53
  • 1
    Thanks Tamir for your answe. Basically I came up with another solution for this problem. I just inserted a linear layout into the constraintLayout and then added the 3 buttons into the linear layout. But your solution is also good. I upvoted it. – VanessaF Aug 01 '21 at 11:11
  • 1
    Your solution will make your app slower, the point of constaintLayout is to prevent this nesting layout. when you don't have nested layouts your app (for most cases) will run faster, check [this](https://stackoverflow.com/questions/53813792/nested-constraint-layout-is-it-a-bad-practice-or-not/53814219) for more info – Tamir Abutbul Aug 01 '21 at 11:14
  • Thanks for your comment Tamir. I will stick to my solution with the nested layout (because I have implement it for many fragments). I will check it then later whether the app reacts slowly or not. Honestly I can't imagine that this will make a cruical difference. Further, I have used this construction on many other occassions and so far I have not experienced any difficulties. However, I will check later whether there is in fact a significant difference regarding the runtime as you pointed out. – VanessaF Aug 01 '21 at 12:40
  • 1
    Anyways I accepted your answer as it solves the problem. Thanks for your effort. I really appreciate it. – VanessaF Aug 01 '21 at 12:46
1

Set the button width 0dp of all button and see the magic :)

android:layout_width="0dp"
Sajid Ali
  • 61
  • 6