How to group a 3x3 grid of radio buttons? How to group a 3x3 grid of radio buttons? xml xml

How to group a 3x3 grid of radio buttons?


Actually it's not that hard if you subclass TableLayout like in this example

/** *  */package com.codtech.android.view;import android.content.Context;import android.util.AttributeSet;import android.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.widget.RadioButton;import android.widget.TableLayout;import android.widget.TableRow;/** * @author diego * */public class ToggleButtonGroupTableLayout extends TableLayout  implements OnClickListener {    private static final String TAG = "ToggleButtonGroupTableLayout";    private RadioButton activeRadioButton;    /**      * @param context     */    public ToggleButtonGroupTableLayout(Context context) {        super(context);        // TODO Auto-generated constructor stub    }    /**     * @param context     * @param attrs     */    public ToggleButtonGroupTableLayout(Context context, AttributeSet attrs) {        super(context, attrs);        // TODO Auto-generated constructor stub    }    @Override    public void onClick(View v) {        final RadioButton rb = (RadioButton) v;        if ( activeRadioButton != null ) {            activeRadioButton.setChecked(false);        }        rb.setChecked(true);        activeRadioButton = rb;    }    /* (non-Javadoc)     * @see android.widget.TableLayout#addView(android.view.View, int, android.view.ViewGroup.LayoutParams)     */    @Override    public void addView(View child, int index,            android.view.ViewGroup.LayoutParams params) {        super.addView(child, index, params);        setChildrenOnClickListener((TableRow)child);    }    /* (non-Javadoc)     * @see android.widget.TableLayout#addView(android.view.View, android.view.ViewGroup.LayoutParams)     */    @Override    public void addView(View child, android.view.ViewGroup.LayoutParams params) {        super.addView(child, params);        setChildrenOnClickListener((TableRow)child);    }    private void setChildrenOnClickListener(TableRow tr) {        final int c = tr.getChildCount();        for (int i=0; i < c; i++) {            final View v = tr.getChildAt(i);            if ( v instanceof RadioButton ) {                v.setOnClickListener(this);            }        }    }    public int getCheckedRadioButtonId() {        if ( activeRadioButton != null ) {            return activeRadioButton.getId();        }        return -1;    }}

and create a layout like this (of course you need to clean it up but you got the idea)

<?xml version="1.0" encoding="utf-8"?><com.codtech.android.view.ToggleButtonGroupTableLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="wrap_content" android:layout_height="wrap_content"    android:id="@+id/radGroup1">    <TableRow>            <RadioButton android:id="@+id/rad1" android:text="Button1"                android:layout_width="105px" android:layout_height="wrap_content"                android:textSize="13px" />            <RadioButton android:id="@+id/rad2" android:text="Button2"                android:layout_width="105px" android:textSize="13px"                android:layout_height="wrap_content" />            <RadioButton android:id="@+id/rad3" android:text="Button3"                android:layout_width="105px" android:textSize="13px"                android:layout_height="wrap_content" />    </TableRow>    <TableRow>            <RadioButton android:id="@+id/rad1" android:text="Button1"                android:layout_width="105px" android:layout_height="wrap_content"                android:textSize="13px" />            <RadioButton android:id="@+id/rad2" android:text="Button2"                android:layout_width="105px" android:textSize="13px"                android:layout_height="wrap_content" />            <RadioButton android:id="@+id/rad3" android:text="Button3"                android:layout_width="105px" android:textSize="13px"                android:layout_height="wrap_content" />    </TableRow>    <TableRow>            <RadioButton android:id="@+id/rad1" android:text="Button1"                android:layout_width="105px" android:layout_height="wrap_content"                android:textSize="13px" />            <RadioButton android:id="@+id/rad2" android:text="Button2"                android:layout_width="105px" android:textSize="13px"                android:layout_height="wrap_content" />            <RadioButton android:id="@+id/rad3" android:text="Button3"                android:layout_width="105px" android:textSize="13px"                android:layout_height="wrap_content" />    </TableRow></com.codtech.android.view.ToggleButtonGroupTableLayout>


After above https://stackoverflow.com/a/2383978/5567009 answer I got another solution for this question, I added some other functionality like, to save the state of the group and also functionality to clear the check functionality like in radio group.

import android.content.Context;import android.os.Parcel;import android.os.Parcelable;import android.support.annotation.IdRes;import android.util.AttributeSet;import android.view.View;import android.widget.RadioButton;import android.widget.TableLayout;import android.widget.TableRow;public class RadioGridGroup extends TableLayout implements View.OnClickListener {    private static final String TAG = "ToggleButtonGroupTableLayout";    private int checkedButtonID = -1;    /**     * @param context     */    public RadioGridGroup(Context context) {        super(context);        // TODO Auto-generated constructor stub    }    /**     * @param context     * @param attrs     */    public RadioGridGroup(Context context, AttributeSet attrs) {        super(context, attrs);        // TODO Auto-generated constructor stub    }    @Override    public void onClick(View v) {        if (v instanceof RadioButton) {            int id = v.getId();            check(id);        }    }    private void setCheckedStateForView(int viewId, boolean checked) {        View checkedView = findViewById(viewId);        if (checkedView != null && checkedView instanceof RadioButton) {            ((RadioButton) checkedView).setChecked(checked);        }    }    /* (non-Javadoc)     * @see android.widget.TableLayout#addView(android.view.View, int, android.view.ViewGroup.LayoutParams)     */    @Override    public void addView(View child, int index,                        android.view.ViewGroup.LayoutParams params) {        super.addView(child, index, params);        setChildrenOnClickListener((TableRow) child);    }    /* (non-Javadoc)     * @see android.widget.TableLayout#addView(android.view.View, android.view.ViewGroup.LayoutParams)     */    @Override    public void addView(View child, android.view.ViewGroup.LayoutParams params) {        super.addView(child, params);        setChildrenOnClickListener((TableRow) child);    }    private void setChildrenOnClickListener(TableRow tr) {        final int c = tr.getChildCount();        for (int i = 0; i < c; i++) {            final View v = tr.getChildAt(i);            if (v instanceof RadioButton) {                v.setOnClickListener(this);            }        }    }    /**     * @return the checked button Id     */    public int getCheckedRadioButtonId() {        return checkedButtonID;    }    /**     * Check the id     *     * @param id     */    public void check(@IdRes int id) {        // don't even bother        if (id != -1 && (id == checkedButtonID)) {            return;        }        if (checkedButtonID != -1) {            setCheckedStateForView(checkedButtonID, false);        }        if (id != -1) {            setCheckedStateForView(id, true);        }        setCheckedId(id);    }    /**     * set the checked button Id     *     * @param id     */    private void setCheckedId(int id) {        this.checkedButtonID = id;    }    public void clearCheck() {        check(-1);    }    @Override    protected void onRestoreInstanceState(Parcelable state) {        if (!(state instanceof SavedState)) {            super.onRestoreInstanceState(state);            return;        }        SavedState ss = (SavedState) state;        super.onRestoreInstanceState(ss.getSuperState());        this.checkedButtonID = ss.buttonId;        setCheckedStateForView(checkedButtonID, true);    }    @Override    protected Parcelable onSaveInstanceState() {        Parcelable superState = super.onSaveInstanceState();        SavedState savedState = new SavedState(superState);        savedState.buttonId = checkedButtonID;        return savedState;    }    static class SavedState extends BaseSavedState {        int buttonId;        /**         * Constructor used when reading from a parcel. Reads the state of the superclass.         *         * @param source         */        public SavedState(Parcel source) {            super(source);            buttonId = source.readInt();        }        /**         * Constructor called by derived classes when creating their SavedState objects         *         * @param superState The state of the superclass of this view         */        public SavedState(Parcelable superState) {            super(superState);        }        @Override        public void writeToParcel(Parcel out, int flags) {            super.writeToParcel(out, flags);            out.writeInt(buttonId);        }        public static final Parcelable.Creator<SavedState> CREATOR =                new Parcelable.Creator<SavedState>() {                    public SavedState createFromParcel(Parcel in) {                        return new SavedState(in);                    }                    public SavedState[] newArray(int size) {                        return new SavedState[size];                    }                };    }}

and use this in XML as follows

<com.test.customviews.RadioGridGroup xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="wrap_content"    android:layout_height="wrap_content">    <TableRow android:layout_marginTop="@dimen/preview_five">        <RadioButton            android:id="@+id/rad1"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="Button1" />        <RadioButton            android:id="@+id/rad2"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="Button2" />    </TableRow>    <TableRow android:layout_marginTop="@dimen/preview_five">        <RadioButton            android:id="@+id/rad3"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="Button3" />        <RadioButton            android:id="@+id/rad4"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="Button4" />    </TableRow>    <TableRow android:layout_marginTop="@dimen/preview_five">        <RadioButton            android:id="@+id/rad5"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="Button5" />        <RadioButton            android:id="@+id/rad6"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="Button6" />    </TableRow>    <TableRow android:layout_marginTop="@dimen/preview_five">        <RadioButton            android:id="@+id/rad7"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="Button7" />        <RadioButton            android:id="@+id/rad8"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="Button8" />    </TableRow></com.test.customviews.RadioGridGroup>

For any other improvements, please comment.


This uses a custom GridLayout with the RadioGroup functionality. Thanks to Saikrishnan Ranganathan for saiaspire/RadioGridGroup

<com.sample.RadioGridGroup        xmlns:grid="http://schemas.android.com/apk/res-auto"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        grid:columnCount="3"        grid:useDefaultMargins="true">        <android.support.v7.widget.AppCompatRadioButton            android:checked="true"            android:text="Text1"            grid:layout_columnWeight="1"/>        <android.support.v7.widget.AppCompatRadioButton            android:text="Text2"            grid:layout_columnWeight="1"/>        <android.support.v7.widget.AppCompatRadioButton            android:text="Text3"            grid:layout_columnWeight="1"/>        <android.support.v7.widget.AppCompatRadioButton            android:text="Text4"            grid:layout_columnWeight="1"/>        <android.support.v7.widget.AppCompatRadioButton            android:text="Text5"            grid:layout_columnWeight="1"/>        <android.support.v7.widget.AppCompatRadioButton            android:text="Text6"            grid:layout_columnWeight="1"/>        <android.support.v7.widget.AppCompatRadioButton            android:text="Text7"            grid:layout_columnWeight="1"/>        <android.support.v7.widget.AppCompatRadioButton            android:text="Text8"            grid:layout_columnWeight="1"/>        <android.support.v7.widget.AppCompatRadioButton            android:text="Text9"            grid:layout_columnWeight="1"/>    </com.sample.RadioGridGroup>