Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android layout with square buttons

I want to make a layout similar to this one:

www.ImageBanana.net - layout.png http://www.imagebanana.com/img/9kmlhy66/thumb/layout.png

Four square buttons on the screen - each of those using half of the screen with/screen height (whichever is smaler). Independent of screen size/resolution.

I already tried to achieve this by using a LinearLayoutbut the buttons are ending up using the correct width, but still having the height of the background (not square any more).

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" 
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <LinearLayout 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">

        <Button 
            android:layout_height="wrap_content" 
            style="@style/CKMainButton"
            android:layout_width="fill_parent" 
            android:text="@string/sights"
            android:id="@+id/ApplicationMainSight" 
            android:layout_toLeftOf="@+id/ApplicationMainEvent"></Button>

        <Button 
            android:layout_height="wrap_content" 
            style="@style/CKMainButton"
            android:layout_width="fill_parent" 
            android:text="@string/sights"
            android:id="@+id/ApplicationMainSight" 
            android:layout_toLeftOf="@+id/ApplicationMainEvent"></Button>

    </LinearLayout>

    <LinearLayout 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">

        <Button 
            android:layout_height="wrap_content" 
            style="@style/CKMainButton"
            android:layout_weight="1" 
            android:layout_width="fill_parent"
            android:text="@string/usergenerated" 
            android:id="@+id/ApplicationMainUserGenerated" />

        <Button 
            android:layout_height="wrap_content" 
            style="@style/CKMainButton"
            android:layout_weight="1" 
            android:layout_width="fill_parent"
            android:text="@string/tours" 
            android:id="@+id/ApplicationMainTour"/>

    </LinearLayout>
</LinearLayout>

It's looking like this: www.ImageBanana.net - layout2.png http://www.imagebanana.com/img/i2ni6g4/thumb/layout2.png

How can i acchieve the Layout to look like the image at the top above?

like image 369
whlk Avatar asked Jun 01 '10 08:06

whlk


5 Answers

import android.content.Context;
import android.util.AttributeSet;
import android.widget.LinearLayout;

public class SquareLayout extends LinearLayout {
    // Desired width-to-height ratio - 1.0 for square
    private final double mScale = 1.0;

    public SquareLayout(Context context) {
        super(context);
    }

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

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);

        if (width > (int)((mScale * height) + 0.5)) {
            width = (int)((mScale * height) + 0.5);
        } else {
            height = (int)((width / mScale) + 0.5);
        }

        super.onMeasure(
                MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
                MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
        );
    }
}
like image 133
Jan Němec Avatar answered Nov 20 '22 19:11

Jan Němec


You can achieve this using ConstraintLayout. You should just add vertical guideline with the position of 50% screen width, align your buttons to the left and right side of the guideline and size them in 1:1 aspect ratio. Everything can be done in layout XML file, no additional source code required.

Once you’ve completed all of these steps, you’ll end up with something like this:

<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">

    <Button
        android:id="@+id/button1"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@android:color/holo_orange_light"
        android:text="1"
        app:layout_constraintDimensionRatio="H,1:1"
        app:layout_constraintEnd_toStartOf="@+id/guideline"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/button2"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@android:color/holo_blue_light"
        android:text="2"
        app:layout_constraintDimensionRatio="W,1:1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/guideline"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/button3"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@android:color/holo_green_dark"
        android:text="3"
        app:layout_constraintDimensionRatio="W,1:1"
        app:layout_constraintEnd_toStartOf="@+id/guideline"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button1" />

    <Button
        android:id="@+id/button4"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@android:color/holo_purple"
        android:text="4"
        app:layout_constraintDimensionRatio="W,1:1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/guideline"
        app:layout_constraintTop_toBottomOf="@+id/button2" />

    <android.support.constraint.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.5" />

</android.support.constraint.ConstraintLayout>

Here's how this layout looks on smallest vs largest screens:

Result view

like image 41
Eugene Brusov Avatar answered Nov 20 '22 17:11

Eugene Brusov


My solution is similar to the first one, however, I do the resizing in the onLayout method. Don't know which one is better.

For convenience I've wrapped my solution in a nice Android Library, see https://github.com/ronaldsteen/Android-SquareLayout-Library

like image 45
Ronald Avatar answered Nov 20 '22 18:11

Ronald


I recommend the following way, it's straightforward and works

public class SquareLayout extends RelativeLayout {

   public SquareLayout(Context context) {
       super(context);
   }

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

   @Override
   public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
       super.onMeasure(widthMeasureSpec, widthMeasureSpec);
   }

}
like image 29
LiangWang Avatar answered Nov 20 '22 19:11

LiangWang


I'm usually doing things like that:

View v; // the view i want to layout squared
v.measure(1,1);
int size = v.getMeasuredHeight(); // or v.getMeasuredWidth()...
LayoutParams params = ... // either your own, or returned from View
params.width = size;
params.height = size;
v.setLayoutParams(params);

This is certainly not the most sophisticated code, as it leaves most capabilities that can be exploited in MeasureSpec, but it gets the job done, as 'v.measure(1,1)' just says "Measure my view as it is!".

The absolute plus in my approach is that you don't have to subclass anything and you don't have to add some OnGlobalLayoutListener to your ViewTreeObserver. This works all at the spot where you build or inflate your layout in code.

like image 2
Bondax Avatar answered Nov 20 '22 19:11

Bondax