RadioGroup和RadioButton 结合使用出现的问题.

1.使用RadioGroup check方法会使 回调接口的onCheckedChanged方法回调两次.check 代码:

  public void check(@IdRes int id) {
        // don't even bother
        if (id != -1 && (id == mCheckedId)) {
            return;
        }

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

        if (id != -1) {
            setCheckedStateForView(id, true);//会调用CheckedStateTracker 类onCheckedChanged方法  
        }

        setCheckedId(id);
    }

setCheckedStateForView(id,true),会调用自己内部的回调方法

private class CheckedStateTracker implements CompoundButton.OnCheckedChangeListener {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            // prevents from infinite recursion
            if (mProtectFromCheckedChange) {
                return;   避免死循环
            }

            mProtectFromCheckedChange = true;
            if (mCheckedId != -1) {
                setCheckedStateForView(mCheckedId, false); //把之前勾选设置为false
            }
            mProtectFromCheckedChange = false;

            int id = buttonView.getId();
            setCheckedId(id); // 这个onCheckedChanged方法跟check方法几乎做同样的事
//    如果没有clearCheck 基本可以简单成 只要check方法 第一条if 语句和第三条if 语句
        }
    }
setCheckedId方法:
   private void setCheckedId(@IdRes int id) {
        mCheckedId = id;
        if (mOnCheckedChangeListener != null) {
            mOnCheckedChangeListener.onCheckedChanged(this, mCheckedId);
        }
      ...
    }

由于调用两次setCheckedId方法,所以会回调两次onCheckedChanged.解决方法就是使用子控件的setChecked方法,但是使用这个方法又引出了另一个问题就是不勾选也会回调onCheckedChanged这点需要判断(setChecked(false)).

2.当一个RadioButton 勾选时,又在初始化方法把这个控件放到最后设置为setCheck(false),点击勾选的时候,会自动设置不勾选状态.这个问题发生在几个fragment切换的时候.发生这个问题在于:

private class CheckedStateTracker implements CompoundButton.OnCheckedChangeListener {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            // prevents from infinite recursion
            if (mProtectFromCheckedChange) {
                return;   避免死循环
            }

            mProtectFromCheckedChange = true;
            if (mCheckedId != -1) {
                setCheckedStateForView(mCheckedId, false); //把之前勾选设置为false
            }
            mProtectFromCheckedChange = false;

            int id = buttonView.getId();
            setCheckedId(id); // 这个onCheckedChanged方法跟check方法几乎做同样的事
//    如果没有clearCheck 基本可以简单成 只要check方法 第一条if 语句和第三条if 语句
        }
    }
当我点击勾选时,由于mCheckId不等于-1 且等于点击的控件id ,这是控件勾选的状态已经为true,调用这个setCheckedStateForView(mCheckedId, false)又把它设置为false......;

解决方法:1重写onChcekedChanged方法,把mCheckedId!=-1改成mCheckedId!=-1&&mCheckedId!=id;2把其他子控件调用setChecked方法与这个点击控件的setChecked方法位置调换,只要不放在后面就可以.3.setCheked后面在增加clearCheck方法,需要注意的是使用clearCheck方法会使onCheckedChanged回调方法的第二个参数为-1.

 

你可能感兴趣的:(android)