这两天做项目使用了RadioGroup和RadioButton,然而,却遇到了一个奇妙的问题?下面我就通过一个小例子来演示下这个奇妙的问题是个神马样子。
1、首先,布局文件如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".RadioGroupActivity">
<RadioGroup
android:id="@+id/rg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RadioButton
android:id="@+id/low"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="低"/>
<RadioButton
android:id="@+id/medium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="中"/>
<RadioButton
android:id="@+id/high"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="高"/>
</RadioGroup>
<Button
android:id="@+id/btSetting"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="设置"/>
</LinearLayout>
2、RadioGroupActivity内容如下:
public class RadioGroupActivity extends AppCompatActivity {
private RadioGroup radioGroup;
private Button btSet;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_radio_group);
radioGroup = findViewById(R.id.rg);
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch(checkedId){
case R.id.low:
Log.d("RadioGroupActivity", "低");
break;
case R.id.medium:
Log.d("RadioGroupActivity", "中");
break;
case R.id.high:
Log.d("RadioGroupActivity", "高");
break;
}
}
});
btSet = findViewById(R.id.btSetting);
btSet.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// radioGroup.check(R.id.low); //该方式会让onCheckedChanged()多次调用
//该方法只执行一次
RadioButton low = findViewById(R.id.low);
low.setChecked(true);
}
});
}
}
3、下面我们这样操作:先选中“高”,然后“设置”按钮设置成“低”,看看log的打印情况。
4、第一种实现方式:在“设置”按钮的点击事件中,我们使用 radioGroup.check(R.id.low)方法来实现,log打印结果如下:
//选中“高”打印的log
2018-12-21 14:29:35.424 10893-10893/com.example.a0306.androiduipro D/RadioGroupActivity: 高
//下面3条是点击“设置”按钮打印的log
2018-12-21 14:29:40.504 10893-10893/com.example.a0306.androiduipro D/RadioGroupActivity: 高
2018-12-21 14:29:40.522 10893-10893/com.example.a0306.androiduipro D/RadioGroupActivity: 低
2018-12-21 14:29:40.523 10893-10893/com.example.a0306.androiduipro D/RadioGroupActivity: 低
5、第二种实现方式:在“设置”按钮的点击事件中,我们使用RadioButton low = findViewById(R.id.low); low.setChecked(true);
方式实现,log打印结果如下:
//选中“高”打印的log
2018-12-21 14:37:07.943 11484-11484/com.example.a0306.androiduipro D/RadioGroupActivity: 高
//点击“设置”按钮打印的log
2018-12-21 14:37:10.415 11484-11484/com.example.a0306.androiduipro D/RadioGroupActivity: 低
6、对比上面两种实现打印的log可以发现,
使用radioGroup.check(R.id.low)方法时,radioGroup的监听回调onCheckedChanged() 方法会被调用多次;
而使用low.setChecked(true)方法时,radioGroup的监听回调onCheckedChanged() 方法只会被调用一次。
7、使用Android到今天,也是今天才发现RadioGroup.check()和RadioButton.setChecked()两个方法竟然有如此的不同,害的自己做项目遇到问题定位了好久才发现,追根溯源,这种差异肯定是源码内部的调用方式不同。
分享一位博主针对这个问题的追根溯源的分析https://drprincess.github.io/2018/05/27/Android-%E4%B8%BA%E4%BB%80%E4%B9%88%20RadioGroup.onCheckedChanged()%20%E4%BC%9A%E8%B0%83%E7%94%A8%E5%A4%9A%E6%AC%A1%EF%BC%9F/