Question

I've been working on a simple soundboard app. The basic design is an imageview for the title, followed by 4 rows of buttons (3 in each row), which makes it look similar to an old cellphone's buttons. At the bottom, there is a "random" and "stop" button. They take up slightly less height space than the rows mentioned above, but the random button was double the width to fill up the space.

To achieve this look, I have been using nested weights and linear layouts. However, upon further research, I have found that this is bad for performance because in my current format, each item is being measured 8 times. My XML layout code is below. I have excluded a lot of UI modifiers such as margins, text, and shadows on the buttons to make the code smaller. The code may seem long, but it is repetitive and simple to understand.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:weightSum="23" >

<!-- Insert Title/Picture in Linear Layout below -->

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_weight="9"
    android:background="@drawable/etho_logo"
    android:orientation="horizontal" >
</LinearLayout>

<!-- Insert Sounds/Buttons in Linear Layout below -->

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_weight="5"
    android:orientation="vertical"
    android:weightSum="4" >

    <!-- This is the 1st line of buttons -->

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="horizontal"
        android:weightSum="3" >

        <Button
            android:id="@+id/bIntro"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/hello_real_select" />

        <Button
            android:id="@+id/bIntro"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/hello_real_select" />

        <Button
            android:id="@+id/bIntro"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/hello_real_select" />
    </LinearLayout>

    <!-- This is the 2nd line of buttons -->

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="horizontal"
        android:weightSum="3" >

        <Button
            android:id="@+id/bIntro"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/hello_real_select" />

        <Button
            android:id="@+id/bIntro"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/hello_real_select" />

        <Button
            android:id="@+id/bIntro"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/hello_real_select" />
    </LinearLayout>

    <!-- This is the 3rd line of buttons -->

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="horizontal"
        android:weightSum="3" >

        <Button
            android:id="@+id/bIntro"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/hello_real_select" />

        <Button
            android:id="@+id/bIntro"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/hello_real_select" />

        <Button
            android:id="@+id/bIntro"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/hello_real_select" />
    </LinearLayout>

    <!-- This is the 4th line of buttons -->

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="horizontal"
        android:weightSum="3" >

        <Button
            android:id="@+id/bIntro"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/hello_real_select" />

        <Button
            android:id="@+id/bIntro"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/hello_real_select" />

        <Button
            android:id="@+id/bIntro"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/hello_real_select" />
    </LinearLayout>
</LinearLayout>

<!-- Random Button and Stop button below here -->

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_weight="9"
    android:orientation="horizontal"
    android:weightSum="3" >

    <Button
        android:id="@+id/bIntro"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:background="@drawable/hello_real_select" />

    <Button
        android:id="@+id/bIntro"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:background="@drawable/hello_real_select" />
</LinearLayout>

</LinearLayout>

I am new to Android, so even though I have tried using a Relative layout, I have had an extremely hard time working with it. I tried watching tutorials online, but still it never looked right when I used it in my code.

For example, my title image has extra space above and below the actual text I want to display. In Linear Layout with weights, it would automatically become smaller to fit the space I gave it. Not in RelativeLayout though.

I guess what I'm trying to ask here is: How do I make it so my RelativeLayout items are evenly spaced buttons across a few rows (as shown in example above), and how do I make it so ImageViews and other things actually automatically size down to the space I give them? If any more information is needed, please don't hesitate to ask.

Was it helpful?

Solution

You are right that RelativeLayout is difficult to make into tables such as the one you made above. LinearLayout is really ideal for that, which is why the TableLayout and TableRow view groups are subclasses of LinearLayout. I can recommend a couple of alternatives besides RelativeLayout that will increase layout efficiency, however.

First, you can eliminate the second vertically oriented LinearLayout and change the layout weight of the first 4 rows of buttons from 1 to 1.25. This will reduce the number of layout passes from 8 to 4, which is the best you can do for a table.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:weightSum="23" >

    <!-- Insert Title/Picture in Linear Layout below -->

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="9"
        android:background="@drawable/etho_logo"
        android:orientation="horizontal" >
    </LinearLayout>

    <!-- This is the 1st line of buttons -->

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1.25"
        android:orientation="horizontal"
        android:weightSum="3" >

        <!-- 3 buttons here -->

    </LinearLayout>

    <!-- This is the 2nd line of buttons -->

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1.25"
        android:orientation="horizontal"
        android:weightSum="3" >

        <!-- 3 buttons here -->

    </LinearLayout>

    <!-- This is the 3rd line of buttons -->

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1.25"
        android:orientation="horizontal"
        android:weightSum="3" >

        <!-- 3 buttons here -->

    </LinearLayout>

    <!-- This is the 4th line of buttons -->

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1.25"
        android:orientation="horizontal"
        android:weightSum="3" >

        <!-- 3 buttons here -->

    </LinearLayout>

    <!-- Random Button and Stop button below here -->

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="9"
        android:orientation="horizontal"
        android:weightSum="3" >

        <Button
            android:id="@+id/bIntro"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/hello_real_select" />

        <Button
            android:id="@+id/bIntro"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/hello_real_select" />
    </LinearLayout>

</LinearLayout>

Another option is to use a single layout that makes a "flat" grid (a ViewGroup that manages the layout of its children into a table by itself). If you are targeting API level 14+ for your app, you can look at GridLayout. If you are targeting an API level prior to 14, you might have to make your own. On a final note, please do not confuse GridLayout with the GridView view group, which is meant to be used with lists and will not accomplish what you want.

OTHER TIPS

It is recommended to use widths of 0dp with weight, which should reduce by half the number of measurements (as the wrap_content require a measurement, but 0dp doesn't)

Also, you don't need the imbricated vertical linear layout, as it is already in a linear layout (although it is cleaner for readability, you can remove it for optimization and adjust the weights)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top