最近BOSS提了一个需求,在单选框选中一个后再次点击可以取消这个单选。我们都知道单选框在Android中就是RadioGroup和RadioButton的组合使用,但是一个RadioGroup中的RadioButton一旦选中一个后就必须有一个被选中,在没有做特殊处理的情况下无法取消。我琢磨了下,用了一种方式实现,记录下来万一以后用的到呢。
先看xml代码吧,一个RadioGroup中有4个RadioButton,下方一个TextView用于展示选中的结果:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="70dp">
<RadioGroup
android:id="@+id/rg_st"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RadioButton
android:background="@drawable/shape_frame"
android:theme="@style/MyRadioButton"
android:layout_margin="10dp"
android:gravity="center"
android:text="孙悟空"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent" />
<RadioButton
android:background="@drawable/shape_frame"
android:theme="@style/MyRadioButton"
android:layout_margin="10dp"
android:gravity="center"
android:text="猪八戒"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent" />
<RadioButton
android:background="@drawable/shape_frame"
android:theme="@style/MyRadioButton"
android:layout_margin="10dp"
android:gravity="center"
android:text="沙悟净"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent" />
<RadioButton
android:background="@drawable/shape_frame"
android:theme="@style/MyRadioButton"
android:layout_margin="10dp"
android:gravity="center"
android:text="白龙马"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent" />
</RadioGroup>
</LinearLayout>
<TextView
android:gravity="center"
android:id="@+id/tv_result"
android:layout_width="match_parent"
android:layout_height="100dp" />
</LinearLayout>
再看Java代码,一般我们都是这样处理的:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
initView();
}
private void initView() {
mRgST = (RadioGroup) findViewById(R.id.rg_st);
mTvResult = (TextView) findViewById(R.id.tv_result);
mRgST.setOnCheckedChangeListener(this);
}
@Override
public void onCheckedChanged(RadioGroup radioGroup, @IdRes int i) {
//找到点击的RadioButton
RadioButton radioButton = (RadioButton) findViewById(i);
switch (radioGroup.getId()){
case R.id.rg_st:
//把RadioButton的文字展示到结果区
mTvResult.setText(radioButton.getText());
break;
}
}
再看如和设置选中后再次点击取消选中:
private RadioGroup mRgST;
private TextView mTvResult;
/**
* 定义变量记录选中adioButton的索引
*/
private int position = -1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
initView();
}
private void initView() {
mRgST = (RadioGroup) findViewById(R.id.rg_st);
mTvResult = (TextView) findViewById(R.id.tv_result);
setRadioGroupCheckedListener(mRgST);
// mRgST.setOnCheckedChangeListener(this);
}
@Override
public void onCheckedChanged(RadioGroup radioGroup, @IdRes int i) {
//找到点击的RadioButton
RadioButton radioButton = (RadioButton) findViewById(i);
switch (radioGroup.getId()){
case R.id.rg_st:
//把RadioButton的文字展示到结果区
mTvResult.setText(radioButton.getText());
break;
}
}
/**
* 监听
* @param radioGroup
*/
private void setRadioGroupCheckedListener(final RadioGroup radioGroup) {
//遍历RadioGroup中的所有子View也就是RadioButton
for (int i = 0; i < radioGroup.getChildCount(); i++) {
final RadioButton radioButton = (RadioButton) radioGroup.getChildAt(i);
final int finalI = i;
//监听RadioButton的点击事件
radioButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//以下逻辑是在RadioButton点击后(也就是RadioButton状态改变后)才执行
//清空RadioGroup的选中状态
radioGroup.clearCheck();
//记录选中按钮文字的变量
String result = "";
//判断记录的值是否和点击的索引值是否相同
if (position == finalI){//相同:点击的是同一个RadioButton执行以下逻辑
radioButton.setChecked(false);//设置RadioButton选中状态为false
position = -1;//初始化position的值
result = "";//初始化result的值
}else {//不同:点击的是不同RadioButton
radioButton.setChecked(true);设置RadioButton选中状态为true
position = finalI;//为position赋值
result = (String) radioButton.getText();//为result赋值
}
mTvResult.setText(result);//状态改变后把结果显示到结果区
}
});
}
}
以上是一个Activity中只有一个RadioGroup时的操作,如果有多个如和处理,其实很简单,看xml其实就是复制了上面的一份:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="70dp">
<RadioGroup
android:id="@+id/rg_st"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RadioButton
android:background="@drawable/shape_frame"
android:theme="@style/MyRadioButton"
android:layout_margin="10dp"
android:gravity="center"
android:text="孙悟空"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent" />
<RadioButton
android:background="@drawable/shape_frame"
android:theme="@style/MyRadioButton"
android:layout_margin="10dp"
android:gravity="center"
android:text="猪八戒"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent" />
<RadioButton
android:background="@drawable/shape_frame"
android:theme="@style/MyRadioButton"
android:layout_margin="10dp"
android:gravity="center"
android:text="沙悟净"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent" />
<RadioButton
android:background="@drawable/shape_frame"
android:theme="@style/MyRadioButton"
android:layout_margin="10dp"
android:gravity="center"
android:text="白龙马"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent" />
</RadioGroup>
</LinearLayout>
<TextView
android:gravity="center"
android:id="@+id/tv_result"
android:layout_width="match_parent"
android:layout_height="100dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="70dp">
<RadioGroup
android:id="@+id/rg_lol"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RadioButton
android:background="@drawable/shape_frame"
android:theme="@style/MyRadioButton"
android:layout_margin="10dp"
android:gravity="center"
android:text="盖伦"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent" />
<RadioButton
android:background="@drawable/shape_frame"
android:theme="@style/MyRadioButton"
android:layout_margin="10dp"
android:gravity="center"
android:text="赵信"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent" />
<RadioButton
android:background="@drawable/shape_frame"
android:theme="@style/MyRadioButton"
android:layout_margin="10dp"
android:gravity="center"
android:text="嘉文"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent" />
<RadioButton
android:background="@drawable/shape_frame"
android:theme="@style/MyRadioButton"
android:layout_margin="10dp"
android:gravity="center"
android:text="薇恩"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent" />
</RadioGroup>
</LinearLayout>
<TextView
android:gravity="center"
android:id="@+id/tv_result_lol"
android:layout_width="match_parent"
android:layout_height="100dp" />
</LinearLayout>
再看Java代码:
private RadioGroup mRgST;
private RadioGroup mRgLOL;
private TextView mTvResult;
private TextView mTvResultLOL;
/**
* 定义变量记录选中adioButton的索引
*/
private int position = -1;
private int position_lol = -1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
initView();
}
private void initView() {
mRgST = (RadioGroup) findViewById(R.id.rg_st);
mRgLOL = (RadioGroup) findViewById(R.id.rg_lol);
mTvResult = (TextView) findViewById(R.id.tv_result);
mTvResultLOL = (TextView) findViewById(R.id.tv_result_lol);
setRadioGroupCheckedListener(mRgST,1);
setRadioGroupCheckedListener(mRgLOL,2);
// mRgST.setOnCheckedChangeListener(this);
}
@Override
public void onCheckedChanged(RadioGroup radioGroup, @IdRes int i) {
//找到点击的RadioButton
RadioButton radioButton = (RadioButton) findViewById(i);
switch (radioGroup.getId()){
case R.id.rg_st:
//把RadioButton的文字展示到结果区
mTvResult.setText(radioButton.getText());
break;
}
}
/**
* 监听
* @param radioGroup
*/
private void setRadioGroupCheckedListener(final RadioGroup radioGroup, final int number) {
//遍历RadioGroup中的所有子View也就是RadioButton
for (int i = 0; i < radioGroup.getChildCount(); i++) {
final RadioButton radioButton = (RadioButton) radioGroup.getChildAt(i);
final int finalI = i;
//监听RadioButton的点击事件
radioButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//以下逻辑是在RadioButton点击后(也就是RadioButton状态改变后)才执行
//清空RadioGroup的选中状态
radioGroup.clearCheck();
switch (number){
case 1:
//记录选中按钮文字的变量
String result = "";
//判断记录的值是否和点击的索引值是否相同
if (position == finalI){//相同:点击的是同一个RadioButton执行以下逻辑
radioButton.setChecked(false);//设置RadioButton选中状态为false
position = -1;//初始化position的值
result = "";//初始化result的值
}else {//不同:点击的是不同RadioButton
radioButton.setChecked(true);设置RadioButton选中状态为true
position = finalI;//为position赋值
result = (String) radioButton.getText();//为result赋值
}
mTvResult.setText(result);//状态改变后把结果显示到结果区
break;
case 2:
//记录选中按钮文字的变量
String result_lol = "";
//判断记录的值是否和点击的索引值是否相同
if (position_lol == finalI){//相同:点击的是同一个RadioButton执行以下逻辑
radioButton.setChecked(false);//设置RadioButton选中状态为false
position_lol = -1;//初始化position的值
result_lol = "";//初始化result的值
}else {//不同:点击的是不同RadioButton
radioButton.setChecked(true);设置RadioButton选中状态为true
position_lol = finalI;//为position赋值
result_lol = (String) radioButton.getText();//为result赋值
}
mTvResultLOL.setText(result_lol);//状态改变后把结果显示到结果区
break;
}
}
});
}
}
其实也可以加个按钮A,注册A按钮的点击事件:调取RadioGroup的clearChecked();也可以取消掉选中状态,但是这样的话需要UI做一定改变,也不一定好看。