Search code examples
androidandroid-layoutandroid-linearlayoutandroid-constraintlayout

Which layout should replace LinearLayout in this calculator


I've implemented this simple calculator layout using LinearLayout, but faced with "nested weights" warning from Android Studio.

This is my first attempt to do something for android, so I started reading: TableLayout and GridLayout would have the same problem as I understand, and ConstraintLayout is recommended everywhere.

But I can't figure it out, how to achieve the same result using ConstraintLayout. Is it possible? Is it even worth it to ditch LinearLayout in this case?

enter image description here

My layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:paddingRight="0dp"
        android:paddingTop="10dp"
        android:orientation="vertical"
        android:background="#F5F5F6"

        >
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            tools:text="2 + 2"
            android:textSize="30sp"
            android:gravity="right"
            android:layout_marginRight="10dp"
            />
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            tools:text="4"
            android:textSize="30sp"
            android:textColor="#000"
            android:gravity="right"
            android:layout_marginRight="10dp"
            />
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="2"
        android:orientation="horizontal"
        >
        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="3"
            android:orientation="vertical"
            >
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:background="@color/colorAccent"
                android:orientation="horizontal"
                >

                <Button
                    android:id="@+id/keyboard_num7"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text="7"
                    style="@style/Operand"
                    />
                <Button
                    android:id="@+id/keyboard_num8"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text="8"
                    style="@style/Operand"
                    />
                <Button
                    android:id="@+id/keyboard_num9"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text="9"
                    style="@style/Operand"
                    />
            </LinearLayout>
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:background="@color/colorAccent"
                android:orientation="horizontal"
                >

                <Button
                    android:id="@+id/keyboard_num4"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text="4"
                    style="@style/Operand"
                    />
                <Button
                    android:id="@+id/keyboard_num5"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text="5"
                    style="@style/Operand"
                    />
                <Button
                    android:id="@+id/keyboard_num6"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text="6"
                    style="@style/Operand"
                    />
            </LinearLayout>
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:background="@color/colorAccent"
                android:orientation="horizontal"
                >

                <Button
                    android:id="@+id/keyboard_num1"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text="1"
                    style="@style/Operand"
                    />
                <Button
                    android:id="@+id/keyboard_num2"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text="2"
                    style="@style/Operand"
                    />
                <Button
                    android:id="@+id/keyboard_num3"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text="3"
                    style="@style/Operand"
                    />
            </LinearLayout>
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:background="@color/colorAccent"
                android:orientation="horizontal"
                >

                <Button
                    android:id="@+id/keyboard_num_dot"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text="."
                    style="@style/Operand"
                    />
                <Button
                    android:id="@+id/keyboard_num0"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text="0"
                    style="@style/Operand"
                    />
                <Button
                    android:id="@+id/keyboard_num_del"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text="del"
                    style="@style/Operand"
                    />
            </LinearLayout>

        </LinearLayout>
        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:orientation="vertical"
            android:background="#E1E2E1"
            >

            <Button
                android:id="@+id/keyboard_division"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="÷"
                style="@style/Operator"
                />
            <Button
                android:id="@+id/keyboard_multiplication"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                style="@style/Operator"
                android:text="×"
                />
            <Button
                android:id="@+id/keyboard_minus"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                style="@style/Operator"
                android:text="−"
                />
            <Button
                android:id="@+id/keyboard_plus"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                style="@style/Operator"
                android:text="+"
                />
            <Button
                android:id="@+id/keyboard_equal"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                style="@style/Equal"
                android:text="="
                />

        </LinearLayout>
    </LinearLayout>

</LinearLayout>

Solution

  • Well, to answer my own question "how to achieve the same result using ConstraintLayout"

    I've made it flat using ConstraintLayout, but still don't know whether it was worth it, and how to decide which layout to use when you can use any.

    And is using guidelines with app:layout_constraintGuide_percent and/or chainStyle="spread_inside" with 0 size is somehow better than "nested weights" from performance point of view.

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    
        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guidelineH"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintGuide_percent="0.33"
            android:orientation="horizontal"
            />
        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guidelineV"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintGuide_percent="0.75"
            android:orientation="vertical"
            />
    
        <TextView
            android:id="@+id/formula"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toTopOf="@id/result"
            app:layout_constraintVertical_chainStyle="packed"
            tools:text="2+2"
            android:textSize="36sp"
            android:gravity="right"
            android:layout_marginRight="10dp"
            />
        <TextView
            android:id="@+id/result"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toBottomOf="@id/formula"
            app:layout_constraintBottom_toTopOf="@id/guidelineH"
            app:layout_constraintVertical_chainStyle="packed"
            tools:text="4"
            android:textSize="30sp"
            android:textColor="#000"
            android:gravity="right"
            android:layout_marginRight="10dp"
            />
        <Button
            android:id="@+id/keyboard_num7"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toTopOf="@id/keyboard_num4"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toLeftOf="@id/keyboard_num8"
            app:layout_constraintTop_toBottomOf="@id/guidelineH"
            app:layout_constraintHorizontal_chainStyle="spread_inside"
            app:layout_constraintVertical_chainStyle="spread_inside"
            android:text="7"
            style="@style/Operand"
            />
        <Button
            android:id="@+id/keyboard_num8"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toTopOf="@id/keyboard_num5"
            app:layout_constraintLeft_toRightOf="@id/keyboard_num7"
            app:layout_constraintRight_toLeftOf="@id/keyboard_num9"
            app:layout_constraintTop_toBottomOf="@id/guidelineH"
            app:layout_constraintHorizontal_chainStyle="spread_inside"
            app:layout_constraintVertical_chainStyle="spread_inside"
            android:text="8"
            style="@style/Operand"
            />
        <Button
            android:id="@+id/keyboard_num9"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toTopOf="@id/keyboard_num6"
            app:layout_constraintLeft_toRightOf="@id/keyboard_num8"
            app:layout_constraintRight_toLeftOf="@id/guidelineV"
            app:layout_constraintTop_toBottomOf="@id/guidelineH"
            app:layout_constraintHorizontal_chainStyle="spread_inside"
            app:layout_constraintVertical_chainStyle="spread_inside"
            android:text="9"
            style="@style/Operand"
            />
        <Button
            android:id="@+id/keyboard_num4"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toTopOf="@id/keyboard_num1"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toLeftOf="@id/keyboard_num5"
            app:layout_constraintTop_toBottomOf="@id/keyboard_num7"
            app:layout_constraintHorizontal_chainStyle="spread_inside"
            app:layout_constraintVertical_chainStyle="spread_inside"
            android:text="4"
            style="@style/Operand"
            />
        <Button
            android:id="@+id/keyboard_num5"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toTopOf="@id/keyboard_num2"
            app:layout_constraintLeft_toRightOf="@id/keyboard_num4"
            app:layout_constraintRight_toLeftOf="@id/keyboard_num6"
            app:layout_constraintTop_toBottomOf="@id/keyboard_num8"
            app:layout_constraintHorizontal_chainStyle="spread_inside"
            app:layout_constraintVertical_chainStyle="spread_inside"
            android:text="5"
            style="@style/Operand"
            />
        <Button
            android:id="@+id/keyboard_num6"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toTopOf="@id/keyboard_num3"
            app:layout_constraintLeft_toRightOf="@id/keyboard_num5"
            app:layout_constraintRight_toLeftOf="@id/guidelineV"
            app:layout_constraintTop_toBottomOf="@id/keyboard_num9"
            app:layout_constraintHorizontal_chainStyle="spread_inside"
            app:layout_constraintVertical_chainStyle="spread_inside"
            android:text="6"
            style="@style/Operand"
            />
        <Button
            android:id="@+id/keyboard_num1"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toTopOf="@id/keyboard_num_dot"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toLeftOf="@id/keyboard_num2"
            app:layout_constraintTop_toBottomOf="@id/keyboard_num4"
            app:layout_constraintHorizontal_chainStyle="spread_inside"
            app:layout_constraintVertical_chainStyle="spread_inside"
            android:text="1"
            style="@style/Operand"
            />
        <Button
            android:id="@+id/keyboard_num2"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toTopOf="@id/keyboard_num0"
            app:layout_constraintLeft_toRightOf="@id/keyboard_num1"
            app:layout_constraintRight_toLeftOf="@id/keyboard_num3"
            app:layout_constraintTop_toBottomOf="@id/keyboard_num5"
            app:layout_constraintHorizontal_chainStyle="spread_inside"
            app:layout_constraintVertical_chainStyle="spread_inside"
            android:text="2"
            style="@style/Operand"
            />
        <Button
            android:id="@+id/keyboard_num3"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toTopOf="@id/keyboard_num_del"
            app:layout_constraintLeft_toRightOf="@id/keyboard_num2"
            app:layout_constraintRight_toLeftOf="@id/guidelineV"
            app:layout_constraintTop_toBottomOf="@id/keyboard_num6"
            app:layout_constraintHorizontal_chainStyle="spread_inside"
            app:layout_constraintVertical_chainStyle="spread_inside"
            android:text="3"
            style="@style/Operand"
            />
        <Button
            android:id="@+id/keyboard_num_dot"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toLeftOf="@id/keyboard_num0"
            app:layout_constraintTop_toBottomOf="@id/keyboard_num1"
            app:layout_constraintHorizontal_chainStyle="spread_inside"
            app:layout_constraintVertical_chainStyle="spread_inside"
            android:text="."
            style="@style/Operand"
            />
        <Button
            android:id="@+id/keyboard_num0"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toRightOf="@id/keyboard_num_dot"
            app:layout_constraintRight_toLeftOf="@id/keyboard_num_del"
            app:layout_constraintTop_toBottomOf="@id/keyboard_num2"
            app:layout_constraintHorizontal_chainStyle="spread_inside"
            app:layout_constraintVertical_chainStyle="spread_inside"
            android:text="0"
            style="@style/Operand"
            />
        <Button
            android:id="@+id/keyboard_num_del"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toRightOf="@id/keyboard_num0"
            app:layout_constraintRight_toLeftOf="@id/guidelineV"
            app:layout_constraintTop_toBottomOf="@id/keyboard_num3"
            app:layout_constraintHorizontal_chainStyle="spread_inside"
            app:layout_constraintVertical_chainStyle="spread_inside"
            android:text="del"
            style="@style/Operand"
            />
        <Button
            android:id="@+id/keyboard_division"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toTopOf="@id/keyboard_multiplication"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@id/guidelineH"
            app:layout_constraintLeft_toRightOf="@id/guidelineV"
            app:layout_constraintHorizontal_chainStyle="spread_inside"
            app:layout_constraintVertical_chainStyle="spread_inside"
            android:text="÷"
            style="@style/Operator"
            />
        <Button
            android:id="@+id/keyboard_multiplication"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toTopOf="@id/keyboard_minus"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@id/keyboard_division"
            app:layout_constraintLeft_toRightOf="@id/guidelineV"
            app:layout_constraintHorizontal_chainStyle="spread_inside"
            app:layout_constraintVertical_chainStyle="spread_inside"
            style="@style/Operator"
            android:text="×"
            />
        <Button
            android:id="@+id/keyboard_minus"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toTopOf="@id/keyboard_plus"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@id/keyboard_multiplication"
            app:layout_constraintLeft_toRightOf="@id/guidelineV"
            app:layout_constraintHorizontal_chainStyle="spread_inside"
            app:layout_constraintVertical_chainStyle="spread_inside"
            style="@style/Operator"
            android:text="−"
            />
        <Button
            android:id="@+id/keyboard_plus"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toTopOf="@id/keyboard_equal"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@id/keyboard_minus"
            app:layout_constraintLeft_toRightOf="@id/guidelineV"
            app:layout_constraintHorizontal_chainStyle="spread_inside"
            app:layout_constraintVertical_chainStyle="spread_inside"
            style="@style/Operator"
            android:text="+"
            />
        <Button
            android:id="@+id/keyboard_equal"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintTop_toBottomOf="@id/keyboard_plus"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintLeft_toRightOf="@id/guidelineV"
            app:layout_constraintHorizontal_chainStyle="spread_inside"
            app:layout_constraintVertical_chainStyle="spread_inside"
            style="@style/Equal"
            android:text="="
            />
    </androidx.constraintlayout.widget.ConstraintLayout>