Milos Sretin
Milos Sretin

Reputation: 1748

Android relative layout grid buttons

I'm trying to create letter buttons in relative layout. The main problem is that I cant set buttons to stay 1:1 aspect ratio and to display it proper on screen.

This is what I want to achieve:

enter image description here

Buttons should always be 1:1 and text shout start from button middle. So far I tried with grid layout and put buttons in 5x5 grinds. But if I set button w/h to let's say 50dp on some displays I can see only A B C and half of D.

Also I tried to put on LinearLayout like:

<RelativeLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_above="@id/adSponsor"
    android:layout_below="@id/barSearch"
    android:layout_margin="20dp">

    <LinearLayout

        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:orientation="vertical">

        <LinearLayout
            android:id="@+id/buttonPanel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="5dp"
                android:layout_weight="1"
                android:background="@drawable/letter_button"
                android:gravity="center|top"
                android:text="A"
                android:textAlignment="gravity"
                android:textColor="@color/red"
                android:textSize="@dimen/letter_box_text"
                android:textStyle="bold" />

            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="5dp"
                android:layout_weight="1"
                android:background="@drawable/letter_button"
                android:gravity="center|top"
                android:text="B"
                android:textAlignment="gravity"
                android:textColor="@color/red"
                android:textSize="@dimen/letter_box_text"
                android:textStyle="bold" />

            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="5dp"
                android:layout_weight="1"
                android:background="@drawable/letter_button"
                android:gravity="center|top"
                android:text="C"
                android:textAlignment="gravity"
                android:textColor="@color/red"
                android:textSize="@dimen/letter_box_text"
                android:textStyle="bold" />

            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="5dp"
                android:layout_weight="1"
                android:background="@drawable/letter_button"
                android:gravity="center|top"
                android:text="D"
                android:textAlignment="gravity"
                android:textColor="@color/red"
                android:textSize="@dimen/letter_box_text"
                android:textStyle="bold" />

            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="5dp"
                android:layout_weight="1"
                android:background="@drawable/letter_button"
                android:gravity="center|top"
                android:text="E"
                android:textAlignment="gravity"
                android:textColor="@color/red"
                android:textSize="@dimen/letter_box_text"
                android:textStyle="bold" />

        </LinearLayout>

    </LinearLayout>

</RelativeLayout>

But in this case the buttons are not 1:1 aspect ratio.

Can anybody point me what is the proper way to achieve this. Also, Buttons shout be in middle. The distance between buttons and search bar and buttons between buttons and footer should be the same.

Upvotes: 0

Views: 789

Answers (3)

appworldonline
appworldonline

Reputation: 1

As @iTurki pointed out, you should use weightSum and layout_weight combinations to spread the views evenly across the linearlayout. That said, I understand that you still need to display your characters in square boxes. For this you could use RelativeLayout containing ImageViews and use the ImageView as clickable buttons.

The advantage of ImageView is, you can set transparent square image as a background and use android:adjustViewBounds="true" so that the height of the imageview increases/decreases according to the horizontal width space available to the imageview. your layout should look something like this.

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="5"
>
<RelativeLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
>
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:src="square_transparent_Image.png"
/>
<TextView
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:gravity="center"
android:textAlignment="center"
android:text="A"
/>
</RelativeLayout>
<RelativeLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
>
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:src="square_transparent_Image.png"
/>
<TextView
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:gravity="center"
android:textAlignment="center"
android:text="B"
/>
</RelativeLayout>
<RelativeLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
>
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:src="square_transparent_Image.png"
/>
<TextView
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:gravity="center"
android:textAlignment="center"
android:text="C"
/>
</RelativeLayout>
<RelativeLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
>
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:src="square_transparent_Image.png"
/>
<TextView
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:gravity="center"
android:textAlignment="center"
android:text="D"
/>
</RelativeLayout>
<RelativeLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
>
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:src="square_transparent_Image.png"
/>
<TextView
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:gravity="center"
android:textAlignment="center"
android:text="E"
/>
</RelativeLayout>
</LinearLayout>

Upvotes: 0

N.T.
N.T.

Reputation: 2611

In order to get a square button I would suggest you to subclass the Button class and override the onMeasure method:

public class SquareButton extends Button {
    public SquareButton(Context context) {
        super(context);
    }

    public SquareButton(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public SquareButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public SquareButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        if(width > height) {
            super.onMeasure(heightMeasureSpec, heightMeasureSpec);
        } else {
            super.onMeasure(widthMeasureSpec, widthMeasureSpec);
        }
    }
}

In order to get the even space between the buttons, I'd go as well with the LinearLayout approach and layout_weight set on the Buttons. You can skip setting the weightSum on the parent if your button count per row is variable. In order to have the bottom of the letter start from the middle of the Button, maybe it's worth to try it to see if you can match the paddingBottom property of the Button with the textSize property. If not, I guess you'll have to override the onDraw method as well.

Upvotes: 2

iTurki
iTurki

Reputation: 16398

Ass this in your horizontal LinearLayout:

android:weightSum="5"

And this in your Buttons:

android:layout_weight="1"

This is assuming you have 5 buttons in each row.

Upvotes: 0

Related Questions