radio button-布局里有多个RadioButton,但是不在一个RadioGroup里,怎么让他们选择的时候互斥呢!

问题描述

布局里有多个RadioButton,但是不在一个RadioGroup里,怎么让他们选择的时候互斥呢!

如题,我一个布局里有多个地方用到RadioButton,由于需要,布局复杂导致他们不在一个RadioGroup里,怎么让他们选择的时候互斥呢,有什么好的方法吗,总不是挨个监听设置其他的RadioButton是Checked为false吧。求高手指教

解决方案

用这个RadioGroup,在radiogroup里面写布局,随便怎么布局radiobutton都可以
package com.xhbok.shundai.view;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
import android.widget.RadioButton;

import java.util.ArrayList;
import java.util.List;

public class MutilRadioGroup 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;

/**
 * {@inheritDoc}
 */
public MutilRadioGroup(Context context) {
    super(context);
    setOrientation(VERTICAL);
    init();
}

/**
 * {@inheritDoc}
 */
public MutilRadioGroup(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();
}

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

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

/**
 * set the default checked radio button, without notification the listeners
 */
public void setCheckWithoutNotif(int id){
    if (id != -1 && (id == mCheckedId)) {
        return;
    }

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

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

@Override
public void addView(View child, int index, ViewGroup.LayoutParams params) {
    List<RadioButton> btns = getAllRadioButton(child);
    if(btns != null && btns.size() > 0){
        for(RadioButton button : btns){
            if (button.isChecked()) {
                mProtectFromCheckedChange = true;
                if (mCheckedId != -1) {
                    setCheckedStateForView(mCheckedId, false);
                }
                mProtectFromCheckedChange = false;
                setCheckedId(button.getId());
            }
        }
    }
    super.addView(child, index, params);
}

/**
 * get all radio buttons which are in the view
 * @param child
 */
private List<RadioButton> getAllRadioButton(View child){
    List<RadioButton> btns = new ArrayList<RadioButton>();
    if (child instanceof RadioButton) {
        btns.add((RadioButton) child);
    }else if(child instanceof ViewGroup){
        int counts = ((ViewGroup) child).getChildCount();
        for(int i = 0; i < counts; i++){
            btns.addAll(getAllRadioButton(((ViewGroup) child).getChildAt(i)));
        }
    }
    return btns;
}

/**
 * <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()
 *
 * @attr ref android.R.styleable#MyRadioGroup_checkedButton
 */
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 LayoutParams(getContext(), attrs);
}

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

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

@Override
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
    super.onInitializeAccessibilityEvent(event);
    event.setClassName(MutilRadioGroup.class.getName());
}

@Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
    super.onInitializeAccessibilityNodeInfo(info);
    info.setClassName(MutilRadioGroup.class.getName());
}

/**
 * <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>
 *
 */
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 ViewGroup.LayoutParams#WRAP_CONTENT} and the child's
     * height to  {@link 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(MutilRadioGroup 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
        OnHierarchyChangeListener {
    private OnHierarchyChangeListener mOnHierarchyChangeListener;

    /**
     * {@inheritDoc}
     */
    @SuppressLint("NewApi")
    public void onChildViewAdded(View parent, View child) {
        if (parent == MutilRadioGroup.this ) {
            List<RadioButton> btns = getAllRadioButton(child);
            if(btns != null && btns.size() > 0){
                for(RadioButton btn : btns){
                    int id = btn.getId();
                    // generates an id if it's missing
                    if (id == View.NO_ID && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                        id = View.generateViewId();
                        btn.setId(id);
                    }
                    btn.setOnCheckedChangeListener(
                            mChildOnCheckedChangeListener);
                }
            }
        }

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

    /**
     * {@inheritDoc}
     */
    public void onChildViewRemoved(View parent, View child) {
        if (parent == MutilRadioGroup.this) {
            List<RadioButton> btns = getAllRadioButton(child);
            if(btns != null && btns.size() > 0){
                for(RadioButton btn : btns){
                    btn.setOnCheckedChangeListener(null);
                }
            }
        }

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

}

解决方案二:

name属性定义成相同的

解决方案三:

radio本身就是单选的,它们的共同处是input类型相同、name相同,否则就不是一组radio

解决方案四:

http://bbs.csdn.net/topics/320052186问题差不多,好像并没有啥好的解决方案

解决方案五:

没学过安卓 放在一个groupBox里面可以不

解决方案六:

这个需要遍历出来,分别判断

解决方案七:

这个只能在代码中实现选择逻辑了

解决方案八:

代码中逻辑处理,或者重写,让其可以跨行布局

解决方案九:

时间: 2024-10-20 03:45:22

radio button-布局里有多个RadioButton,但是不在一个RadioGroup里,怎么让他们选择的时候互斥呢!的相关文章

android-在 radio button 和 check box 的右边显示 image

问题描述 在 radio button 和 check box 的右边显示 image 我在做一个多项选择测试.有一些图像作为答案,有单选和多选 <radio button or checkbox here> <image here> 我需要把 drawable folder 里的图像添加在 radiobuttons 或者 checkboxes 的右边.如何实现? 解决方案 在 xml 中添加下面的代码 <RadioButton android:drawableRight=&

Extjs2.0之横向Radio经典布局

我想大家最需要的就是这样的布局 但是找遍google,要么是太复杂在render里添加后续radio,要么是采用FieldSet方式额外加了一大框.但是我想像中需要的却是上面这种方式. 经过测试,上面这样的radio横向布局是可以做到的,关键是采用table的layout及radio行的isFormField设置为true,设置isFormField这点尤其重要,因为panel默认不是属于FormField的,因此即使设置了fieldLabel属性也不不会显示label. 生成此window的j

android中radio button居中对齐的问题

问题描述 android中radio button居中对齐的问题 我使用以下代码动态的生成了 RadioButtons: RadioButton radioButton=new RadioButton(context); LayoutParams layoutParams=new LayoutParams(radioWidthradioHeight);layoutParams.gravity=Gravity.CENTER;radioButton.setLayoutParams(layoutPar

MFC中Radio Button的用法详解_C 语言

本文通过针对两个常见问题的解决方案,详细阐述了MFC中Radio Button的用法.有助于读者加深对于MFC运行机制及Radio Button控件用法的理解. 首先为对话框加上2个radio button,分别是Radio1和Radio2. 问题1:如何让Radio1或者Radio2默认选上?如何知道哪个被选上了? 关键是选上,"默认"只要放在OnInitDialog()即可.有如下的三种方法可以让它选上: 第一种: ((CButton *)GetDlgItem(IDC_RADIO1

easyUI treegrid 加了一列radio button 怎么获取radio的值?

问题描述 easyUI treegrid 加了一列radio button 怎么获取radio的值? 获取到的orgtype是undefined 代码如下: <th data-options="field:'orgtype',width:80,formatter:formatP">类型</th> function formatP(value){ var s = '<input type="radio" value="1&quo

自定义的html radio button的样式

设计要求效果如下: 平时看到的radio button效果如下: 可以看出设计上图的radio button选中和没有选中的状态都有自定义的图片样式.但是我们使用radio button基本上都是需要在互斥的一组.我们需要保持radio button本身的功能,同时又需要自定义的它的样式.之前项目中大家都是能使用传统的radio button过了就过了,也没有怎么研究.这次项目,我尝试使用了一些方法,可以达到自定义的radio button的样式. 4个选项的结构都相同,只是内容有所改变,结构如

radio button-请教一个group box和 radio BUTTON的问题

问题描述 请教一个group box和 radio BUTTON的问题 在一个组框里面放上四个单选按钮,如果想把四个单选每个都添加成员控件变量的话,还得把每个的GROUP改成TRUE(启动程序后四个单选竟然可以全部选中,),之后还得改回FALSE功能才能正常,请问这是为什么呀?改来改去怪麻烦的,有没有其它的方法呀? 解决方案 直接用group控件把4个radio包裹起来,然后选择的时候,你可以用控件ID来获取选中的是哪个变量

MFC一个关于radio button的问题

问题描述 MFC一个关于radio button的问题 在界面上放置两组radio button,每组三个,要求两组各自能三选一,如果不用组框,请问怎么设置? 解决方案 http://blog.csdn.net/c_cyoxi/article/details/23868979 解决方案二: 使用 CButton 对象创建按钮,并使用BS_RADIOBUTTON 参数,为需要分组的按钮设置相同的 group 属性即可

用prototype 方法$A() uncheck radio button

做无刷新页面的时候,会碰到无法从服务器取list的size,每条list都有一个radio button, 这时候想uncheck所有radio的时候,可以用prototype方法来完成遍历: <input type="radio" name="selectedGrie" value=''> var idxs=$('selectedGrie'); var nodes=$A(idxs); nodes.each(function(node){ node.ch