必威体育Betway必威体育官网
当前位置:首页 > IT技术

自定义RadioGroup实现多行排列

时间:2019-09-28 10:43:16来源:IT技术作者:seo实验室小编阅读:60次「手机版」
 

radiogroup

今天做一个单选框,效果如下:

这里需要自定义一个radiogroup

package yisu.cn.wedgit;

import Android.content.context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.compoundbutton;
import android.widget.Linearlayout;
import android.widget.radiobutton;

public class MyRadioGroup extends LinearLayout {
    // holds the checked id; the selection is empty by default
    private int mCheckedId = -1;
    // tracks children radio buttons checked state
    private CompoundButton.OnCheckedChangeListener mChildOnCheckedChangeListener;
    // when true, mOnCheckedChangeListener discards events
    private boolean mProtectFromCheckedChange = false;
    private OnCheckedChangeListener mOnCheckedChangeListener;
    private PassThroughHierarchyChangeListener mPassThroughListener;

    public MyRadioGroup(Context context) {
        super(context);
        setOrientation(VERTICAL);
        init();
    }

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

    private void init() {
        mChildOnCheckedChangeListener = new CheckedStateTracker();
        mPassThroughListener = new PassThroughHierarchyChangeListener();
        super.setOnHierarchyChangeListener(mPassThroughListener);
    }

    @Override
    public void setOnHierarchyChangeListener(OnHierarchyChangeListener listener) {
        // the user listener is delegated to our pass-through listener
        mPassThroughListener.mOnHierarchyChangeListener = listener;
    }

    @Override
    protected void onfinishinflate() {
        super.onFinishInflate();

        // checks the APPropriate radio button as requested in the XML file
        if (mCheckedId != -1) {
            mProtectFromCheckedChange = true;
            setCheckedStateForView(mCheckedId, true);
            mProtectFromCheckedChange = false;
            setCheckedId(mCheckedId);
        }
    }

    @Override
    public void addView(View child, int index, ViewGroup.layoutparams params) {
        if (child instanceof RadioButton) {
            final RadioButton button = (RadioButton) child;
            if (button.isChecked()) {
                mProtectFromCheckedChange = true;
                if (mCheckedId != -1) {
                    setCheckedStateForView(mCheckedId, false);
                }
                mProtectFromCheckedChange = false;
                setCheckedId(button.getId());
            }
        } else if (child instanceof ViewGroup) {
            int num = ((ViewGroup)child).getChildCount();
            for (int i = 0; i < num; i++) {//这里要循环
                final RadioButton button = findRadioButton((ViewGroup) (((ViewGroup) child).getChildAt(i)));
                if (button.isChecked()) {
                    mProtectFromCheckedChange = true;
                    if (mCheckedId != -1) {
                        setCheckedStateForView(mCheckedId, false);
                    }
                    mProtectFromCheckedChange = false;
                    setCheckedId(button.getId());
                }
            }

        }

        super.addView(child, index, params);
    }

    /** 查找radioButton控件 */
    public RadioButton findRadioButton(ViewGroup group) {

        RadioButton resBtn = null;
        int len = group.getChildCount();
        for (int i = 0; i < len; i++) {
            if (group.getChildAt(i) instanceof RadioButton) {
                resBtn = (RadioButton) group.getChildAt(i);
                break;
            } else if (group.getChildAt(i) instanceof ViewGroup) {
                resBtn = findRadioButton((ViewGroup) group.getChildAt(i));
                break;
            }
        }
        return resBtn;
    }

    /**
     * <p>
     * Sets the selection to the radio button whose identifier is passed in
     * parameter. Using -1 as the selection identifier clears the selection;
     * such an operation is equivalent to invoking {@link #clearCheck()}.
     * </p>
     *
     * @param id
    *            the unique id of the radio button to select in this group
     *
     * @see #getCheckedRadioButtonId()
     * @see #clearCheck()
     */
    public void check(int id) {
        // don't even bother
        if (id != -1 && (id == mCheckedId)) {
            return;
        }

        if (mCheckedId != -1) {
            setCheckedStateForView(mCheckedId, false);
        }

        if (id != -1) {
            setCheckedStateForView(id, true);
        }

        setCheckedId(id);
    }

    private void setCheckedId(int id) {
        mCheckedId = id;
        if (mOnCheckedChangeListener != null) {
            mOnCheckedChangeListener.onCheckedChanged(this, mCheckedId);
        }
    }

    private void setCheckedStateForView(int viewId, boolean checked) {
        View checkedView = findViewById(viewId);
        if (checkedView != null && checkedView instanceof RadioButton) {
            ((RadioButton) checkedView).setChecked(checked);
        }
    }

    /**
     * <p>
     * Returns the identifier of the selected radio button in this group. Upon
     * empty selection, the returned value is -1.
     * </p>
     *
     * @return the unique id of the selected radio button in this group
     *
     * @see #check(int)
     * @see #clearCheck()
     */
    public int getCheckedRadioButtonId() {
        return mCheckedId;
    }

    /**
     * <p>
     * Clears the selection. When the selection is cleared, no radio button in
     * this group is selected and {@link #getCheckedRadioButtonId()} returns
     * null.
     * </p>
     *
     * @see #check(int)
     * @see #getCheckedRadioButtonId()
     */
    public void clearCheck() {
        check(-1);
    }

    /**
     * <p>
     * Register a callback to be invoked when the checked radio button changes
     * in this group.
     * </p>
     *
     * @param listener
    *            the callback to call on checked state change
     */
    public void setOnCheckedChangeListener(OnCheckedChangeListener listener) {
        mOnCheckedChangeListener = listener;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public LayoutParams generateLayoutParams(AttributeSet attrs) {
        return new MyRadioGroup.LayoutParams(getContext(), attrs);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
        return p instanceof MyRadioGroup.LayoutParams;
    }

    @Override
    protected LinearLayout.LayoutParams generatedefaultLayoutParams() {
        return new LayoutParams(LayoutParams.wrap_content,
                LayoutParams.WRAP_CONTENT);
    }

    /**
     * <p>
     * This set of layout parameters defaults the width and the height of the
     * children to {@link #WRAP_CONTENT} when they are not specified in the XML
     * file. Otherwise, this class ussed the value read from the XML file.
     * </p>
     *
     * <p>
     * See  for a list of all child view attributes that this class
     * supports.
     * </p>
     *
     */
    //{@link android.R.styleable#LinearLayout_Layout LinearLayout
        //* Attributes}
    public static class LayoutParams extends LinearLayout.LayoutParams {
        /**
         * {@inheritDoc}
         */
        public LayoutParams(Context c, AttributeSet attrs) {
            super(c, attrs);
        }

        /**
         * {@inheritDoc}
         */
        public LayoutParams(int w, int h) {
            super(w, h);
        }

        /**
         * {@inheritDoc}
         */
        public LayoutParams(int w, int h, float initWeight) {
            super(w, h, initWeight);
        }

        /**
         * {@inheritDoc}
         */
        public LayoutParams(ViewGroup.LayoutParams p) {
            super(p);
        }

        /**
         * {@inheritDoc}
         */
        public LayoutParams(MarginLayoutParams source) {
            super(source);
        }

        /**
         * <p>
         * Fixes the child's width to
         * {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} and the
         * child's height to
         * {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} when not
         * specified in the XML file.
         * </p>
         *
         * @param a
        *            the styled attributes set
         * @param widthAttr
        *            the width attribute to fetch
         * @param heightAttr
        *            the height attribute to fetch
         */
        @Override
        protected void setBaseAttributes(TypedArray a, int widthAttr,
                                         int heightAttr) {

            if (a.hasValue(widthAttr)) {
                width = a.getLayoutDimension(widthAttr, "layout_width");
            } else {
                width = WRAP_CONTENT;
            }

            if (a.hasValue(heightAttr)) {
                height = a.getLayoutDimension(heightAttr, "layout_height");
            } else {
                height = WRAP_CONTENT;
            }
        }
    }

    /**
     * <p>
     * Interface definition for a callback to be invoked when the checked radio
     * button changed in this group.
     * </p>
     */
    public interface OnCheckedChangeListener {
        /**
         * <p>
         * Called when the checked radio button has changed. When the selection
         * is cleared, checkedId is -1.
         * </p>
         *
         * @param group
        *            the group in which the checked radio button has changed
         * @param checkedId
        *            the unique identifier of the newly checked radio button
         */
        public void onCheckedChanged(MyRadioGroup group, int checkedId);
    }

    private class CheckedStateTracker implements
           CompoundButton.OnCheckedChangeListener {
        public void onCheckedChanged(CompoundButton buttonView,
                                     boolean isChecked) {
            // prevents from infinite recursion
            if (mProtectFromCheckedChange) {
                return;
            }

            mProtectFromCheckedChange = true;
            if (mCheckedId != -1) {
                setCheckedStateForView(mCheckedId, false);
            }
            mProtectFromCheckedChange = false;

            int id = buttonView.getId();
            setCheckedId(id);
        }
    }

    /**
     * <p>
     * A pass-through listener acts upon the events and dispatches them to
     * another listener. This allows the table layout to set its own internal
     * hierarchy change listener without preventing the user to setup his.
     * </p>
     */
    private class PassThroughHierarchyChangeListener implements
           ViewGroup.OnHierarchyChangeListener {
        private ViewGroup.OnHierarchyChangeListener mOnHierarchyChangeListener;

        public void onChildViewAdded(View parent, View child) {
            if (parent == MyRadioGroup.this && child instanceof RadioButton) {
                int id = child.getId();
                // generates an id if it's missing
                if (id == View.NO_ID) {
                    id = child.hashCode();
                    child.setId(id);
                }
                ((RadioButton) child)
                        .setOnCheckedChangeListener(mChildOnCheckedChangeListener);
            } else if (parent == MyRadioGroup.this
                   && child instanceof ViewGroup) {
                int num = ((ViewGroup)child).getChildCount();
                for (int i = 0; i < num; i++) {
                    RadioButton btn = findRadioButton((ViewGroup) (((ViewGroup) child).getChildAt(i)));
                    int id = btn.getId();
                    // generates an id if it's missing
                    if (id == View.NO_ID) {
                        id = btn.hashCode();
                        btn.setId(id);
                    }
                    btn.setOnCheckedChangeListener(mChildOnCheckedChangeListener);
                }

            }

            if (mOnHierarchyChangeListener != null) {
                mOnHierarchyChangeListener.onChildViewAdded(parent, child);
            }
        }

        public void onChildViewRemoved(View parent, View child) {
            if (parent == MyRadioGroup.this && child instanceof RadioButton) {
                ((RadioButton) child).setOnCheckedChangeListener(null);
            } else if (parent == MyRadioGroup.this
                   && child instanceof ViewGroup) {
                int num = ((ViewGroup)child).getChildCount();
                for (int i = 0; i < num; i++) {
                    findRadioButton((ViewGroup) (((ViewGroup) child).getChildAt(i))).setOnCheckedChangeListener(
                            null);
                }

            }
            if (mOnHierarchyChangeListener != null) {
                mOnHierarchyChangeListener.onChildViewRemoved(parent, child);
            }
        }
    }
}
在布局文件中这样调用代码即可:

<yisu.cn.wedgit.MyRadioGroup
   android:id="@+id/layout_check"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:orientation="vertical"
  
   >

    <LinearLayout
       android:layout_width="fill_parent"
       android:layout_height="wrap_content"
       android:layout_marginleft="@dimen/margin_left_normal"
       android:layout_marginRight="@dimen/margin_left_normal"
       android:layout_weight="1"
       android:orientation="horizontal">

        <LinearLayout
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:layout_below="@id/layout_check"
           android:layout_weight="1"
           android:orientation="horizontal"
          
           >

            <RadioButton
               android:id="@+id/kf"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:layout_gravity="center_vertical"
               android:layout_weight="1"
               android:background="@drawable/checkbox_bloodsugar"
               android:button="@null"
               android:checked="true"
               android:gravity="center"
               android:paddingBottom="@dimen/control_top_distance"
               android:paddingLeft="@dimen/control_distance"
               android:paddingRight="@dimen/control_distance"
               android:paddingTop="@dimen/control_top_distance"
               android:text="@string/kf"
               android:textcolor="@color/check_select"
               />

        </LinearLayout>

        <LinearLayout
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:layout_below="@id/layout_check"
           android:layout_weight="1"

           android:orientation="horizontal"
           >

            <RadioButton
               android:id="@+id/zch"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:layout_gravity="center_vertical"
               android:layout_weight="1"
               android:background="@drawable/checkbox_bloodsugar"
               android:button="@null"
               android:checked="false"
               android:gravity="center"
               android:paddingBottom="@dimen/control_top_distance"
               android:paddingLeft="@dimen/control_distance"
               android:paddingRight="@dimen/control_distance"
               android:paddingTop="@dimen/control_top_distance"
               android:text="@string/zch"
               android:textColor="@color/check_select"
               />

        </LinearLayout>

        <LinearLayout
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:layout_below="@id/layout_check"
           android:layout_weight="1"
           android:orientation="horizontal"
          
           >

            <RadioButton
               android:id="@+id/wcq"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:layout_gravity="center_vertical"
               android:layout_weight="1"
               android:background="@drawable/checkbox_bloodsugar"
               android:button="@null"
               android:checked="false"
               android:gravity="center"
               android:paddingBottom="@dimen/control_top_distance"
               android:paddingLeft="@dimen/control_distance"
               android:paddingRight="@dimen/control_distance"
               android:paddingTop="@dimen/control_top_distance"
               android:text="@string/wcq"
               android:textColor="@color/check_select"
               />

        </LinearLayout>

        <LinearLayout
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:layout_below="@id/layout_check"
           android:layout_weight="1"
           android:orientation="horizontal"
          
           >

            <RadioButton
               android:id="@+id/wch"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:layout_gravity="center_vertical"
               android:layout_weight="1"
               android:background="@drawable/checkbox_bloodsugar"
               android:button="@null"
               android:checked="false"
               android:gravity="center"
               android:paddingBottom="@dimen/control_top_distance"
               android:paddingLeft="@dimen/control_distance"
               android:paddingRight="@dimen/control_distance"
               android:paddingTop="@dimen/control_top_distance"
               android:text="@string/wch"
               android:textColor="@color/check_select"
               />

        </LinearLayout>
    </LinearLayout>

    <LinearLayout
       android:layout_width="fill_parent"
       android:layout_height="wrap_content"
       android:layout_marginLeft="@dimen/margin_left_normal"
       android:layout_marginRight="@dimen/margin_left_normal"
       android:layout_weight="1"
       android:orientation="horizontal">

        <LinearLayout
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:layout_below="@id/layout_check"
           android:layout_weight="1"
           android:orientation="horizontal"
         
           >

            <RadioButton
               android:id="@+id/wancq"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:layout_gravity="center_vertical"
               android:layout_weight="1"
               android:background="@drawable/checkbox_bloodsugar"
               android:button="@null"
               android:checked="false"
               android:gravity="center"
               android:paddingBottom="@dimen/control_top_distance"
               android:paddingLeft="@dimen/control_distance"
               android:paddingRight="@dimen/control_distance"
               android:paddingTop="@dimen/control_top_distance"
               android:text="@string/wancq"
               android:textColor="@color/check_select"
               />

        </LinearLayout>

        <LinearLayout
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:layout_below="@id/layout_check"
           android:layout_weight="1"

           android:orientation="horizontal"
           >

            <RadioButton
               android:id="@+id/wanch"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:layout_gravity="center_vertical"
               android:layout_weight="1"
               android:background="@drawable/checkbox_bloodsugar"
               android:button="@null"
               android:checked="false"
               android:gravity="center"
               android:paddingBottom="@dimen/control_top_distance"
               android:paddingLeft="@dimen/control_distance"
               android:paddingRight="@dimen/control_distance"
               android:paddingTop="@dimen/control_top_distance"
               android:text="@string/wanch"
               android:textColor="@color/check_select"
               />

        </LinearLayout>

        <LinearLayout
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:layout_below="@id/layout_check"
           android:layout_weight="1"
           android:orientation="horizontal"
         
           >

            <RadioButton
               android:id="@+id/sq"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:layout_gravity="center_vertical"
               android:layout_weight="1"
               android:background="@drawable/checkbox_bloodsugar"
               android:button="@null"
               android:checked="false"
               android:gravity="center"
               android:paddingBottom="@dimen/control_top_distance"
               android:paddingLeft="@dimen/control_distance"
               android:paddingRight="@dimen/control_distance"
               android:paddingTop="@dimen/control_top_distance"
               android:text="@string/sq"
               android:textColor="@color/check_select"
               />

        </LinearLayout>

        <LinearLayout
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:layout_below="@id/layout_check"
           android:layout_weight="1"
           android:orientation="horizontal"
       
           >

            <RadioButton
               android:id="@+id/wz"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:layout_gravity="center_vertical"
               android:layout_weight="1"
               android:background="@drawable/checkbox_bloodsugar"
               android:button="@null"
               android:checked="false"
               android:gravity="center"
               android:paddingBottom="@dimen/control_top_distance"
               android:paddingLeft="@dimen/control_distance"
               android:paddingRight="@dimen/control_distance"
               android:paddingTop="@dimen/control_top_distance"
               android:text="@string/wz"
               android:textColor="@color/check_select"
               />

        </LinearLayout>
    </LinearLayout>

</yisu.cn.wedgit.MyRadioGroup>
在Activity中只有实现自定义的MyRadioGruop中的OnCheckedChangeListener接口即可监听单选框的选择状态。



相关阅读

线程间通信的几种实现方式

线程间通信的几种实现方式 首先,要短信线程间通信的模型有两种:共享内存和消息传递,以下方式都是基本这两种模型来实现的。我们来基

用C语言实现一个C语言的编译器

用C语言实现一个C语言的编译器 目标:基于C0+文法的编译器,生成语法树,四元式,符号表,最后生成X86汇编(386) 接下来介绍一下整个的设计和

triplet loss (原理 + 实现)

一、triplet loss 原理 triplet:一个三元组,这个三元组是这样构成的:从训练数据集中随机选一个样本,该样本称为Anchor,然后再随机选取

Gamma校正原理及实现

gamma校正原理:假设图像中有一个像素,值是 200 ,那么对这个像素进行校正必须执行如下步骤: 1. 归一化 :将像素值转换为  0 ~ 1  之间

Vue中使用 transition标签或transition-group标签以及

Vue的动画并没有非常炫酷的效果,不过也是有一些实用性的,在项目中有的地方使用,也是能够营造出不同的效果 下面为大家列举两个简单实

分享到:

栏目导航

推荐阅读

热门阅读