Search code examples
androidandroid-layoutandroid-tablelayout

How to create exactly square buttons that fill in width of screen


I've an activity that fill with some buttons dynamically base on TableLayout and TableRow like this:

    private TableLayout buttonTableLayout;
    //-----
    for (int row = 0; row < buttonTableLayout.getChildCount(); ++row)
        ((TableRow) buttonTableLayout.getChildAt(row)).removeAllViews();

    LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    for (int row = 0; row < 5; row++) {
        TableRow currentTableRow = getTableRow(row);

        for (int column = 0; column < 5; column++) {
                Button newGuessButton = (Button) inflater.inflate(R.layout.my_button, currentTableRow, false);
                newGuessButton.setText(String.valueOf((row * 5) + column + 1));
                currentTableRow.addView(newGuessButton);
            }

        }
    }
    //----
    private TableRow getTableRow(int row) {
        return (TableRow) buttonTableLayout.getChildAt(row);
    }

I want to make a 5*5 list of buttons that 1:All of them has the same width and height and 2: make them fill of screen. In my code I have a layout that named my_button, like :

<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/newButton"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@drawable/button_style"></Button>

or

<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/newButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/button_style"></Button>

and results is: enter image description here enter image description here

I have change the gravity but it doesn't works.Is there any way to make them exactly square and fill the width of screen.


Solution

  • Updated 2022:

    Now we can do it easily with ConstraintLayout and app:layout_constraintDimensionRatio="1:1". This is the google guide link.

    <?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"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:text="My Button"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintDimensionRatio="1:1"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    Previous answer: You should sub-class Button view and override below function:

    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);
        }
    
        public SquareButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
            super(context, attrs, defStyleAttr, defStyleRes);
        }
    
        @Override
        public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, widthMeasureSpec);
            int width = MeasureSpec.getSize(widthMeasureSpec);
            int height = MeasureSpec.getSize(heightMeasureSpec);
            int size = width > height ? height : width;
            setMeasuredDimension(size, size); // make it square
        }
    
    }
    

    Edit: Ok, you need to customize your button as above. Then, instead of using the default button, you can use the above SquareButton.

     <com.kingfisher.utils.SquareButton
                android:id="@+id/btnSearch"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="100"
                android:text="Downloaded"/>