Android RadioGroup实现多行显示,并保持单选

公司项目最近有个这样的需求,要求实现【多个文本,多行显示,且同时只能选中一个】。设计图效果如下:

看上去很简单,使用 RadioGroup + LinearLayout + RadioButton 快速实现:

XML 复制代码
<RadioGroup
	android:id="@+id/rg"
	android:layout_width="match_parent"
	android:layout_height="match_parent"
	android:layout_marginLeft="@dimen/SIZE_18"
	android:layout_marginTop="@dimen/SIZE_9"
	android:layout_marginRight="@dimen/SIZE_18"
	android:layout_marginBottom="@dimen/SIZE_20">

	<LinearLayout
		android:layout_width="match_parent"
		android:layout_height="wrap_content"
		android:orientation="horizontal">

		<RadioButton
			android:id="@+id/RadioButton1"
			style="@style/fontStyle"
			android:layout_width="wrap_content"
			android:layout_height="28dp"
			android:background="@drawable/bg_button_bg"
			android:button="@null"
			android:paddingLeft="@dimen/SIZE_10"
			android:paddingRight="@dimen/SIZE_10"
			android:text="@string/str_abnormal_function"
			android:textColor="@drawable/text_color_select"
			android:textSize="@dimen/SP_SIZE_12"></RadioButton>

		<RadioButton
			android:id="@+id/RadioButton2"
			android:layout_width="wrap_content"
			android:layout_height="28dp"
			android:layout_marginLeft="@dimen/SIZE_10"
			android:autoSizeMaxTextSize="18sp"
			android:autoSizeMinTextSize="6sp"
			android:autoSizeStepGranularity="1sp"
			android:autoSizeTextType="uniform"
			android:background="@drawable/bg_button_bg"
			android:button="@null"
			android:paddingLeft="@dimen/SIZE_10"
			android:paddingRight="@dimen/SIZE_10"
			android:text="@string/str_experience_problem"
			android:textColor="@drawable/text_color_select"
			android:textSize="@dimen/SP_SIZE_12"></RadioButton>

		<RadioButton
			android:id="@+id/RadioButton3"
			style="@style/fontStyle"
			android:layout_width="wrap_content"
			android:layout_height="28dp"
			android:layout_marginLeft="@dimen/SIZE_10"
			android:background="@drawable/bg_button_bg"
			android:button="@null"
			android:paddingLeft="@dimen/SIZE_10"
			android:paddingRight="@dimen/SIZE_10"
			android:text="@string/str_new_feature_suggestion"
			android:textColor="@drawable/text_color_select"
			android:textSize="@dimen/SP_SIZE_12"></RadioButton>

	</LinearLayout>

	<RadioButton
		android:id="@+id/RadioButton4"
		style="@style/fontStyle"
		android:layout_width="wrap_content"
		android:layout_height="28dp"
		android:layout_marginTop="@dimen/SIZE_9"
		android:background="@drawable/bg_button_bg"
		android:button="@null"
		android:paddingLeft="@dimen/SIZE_10"
		android:paddingRight="@dimen/SIZE_10"
		android:text="@string/str_type_other"
		android:textColor="@drawable/text_color_select"
		android:textSize="@dimen/SP_SIZE_12"></RadioButton>
</RadioGroup>

跑起来后,发现并没有实现单选的效果,究其根本,观其RadioGroup源码:

java 复制代码
@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());
		}
	}

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

RadioGroup在添加子view时,仅判断了其是否是RadioButton,故LinearLayout并不符合这一条件,要想实现内嵌LinearLayout+RadioButton,只能自定义RadioGroup,并重写addView方法。本文使用了另一方式解决这个问题:

使用多个RadioGroup内嵌RadioButton,当其中1个RadioGroup中的RadioButton被选中时,清除其他RadioGroup的选中效果,代码如下:

XML 复制代码
<RadioGroup
	android:id="@+id/rg"
	android:layout_width="match_parent"
	android:layout_height="match_parent"
	android:layout_marginLeft="@dimen/SIZE_18"
	android:layout_marginTop="@dimen/SIZE_9"
	android:layout_marginRight="@dimen/SIZE_18"
	android:orientation="horizontal">

	<RadioButton
		android:id="@+id/RadioButton1"
		style="@style/fontStyle"
		android:layout_width="wrap_content"
		android:layout_height="28dp"
		android:background="@drawable/bg_button_bg"
		android:button="@null"
		android:paddingLeft="@dimen/SIZE_10"
		android:paddingRight="@dimen/SIZE_10"
		android:text="@string/str_abnormal_function"
		android:textColor="@drawable/text_color_select"
		android:textSize="@dimen/SP_SIZE_12" />

	<RadioButton
		android:id="@+id/RadioButton2"
		android:layout_width="wrap_content"
		android:layout_height="28dp"
		android:layout_marginLeft="@dimen/SIZE_10"
		android:autoSizeMaxTextSize="18sp"
		android:autoSizeMinTextSize="6sp"
		android:autoSizeStepGranularity="1sp"
		android:autoSizeTextType="uniform"
		android:background="@drawable/bg_button_bg"
		android:button="@null"
		android:paddingLeft="@dimen/SIZE_10"
		android:paddingRight="@dimen/SIZE_10"
		android:text="@string/str_experience_problem"
		android:textColor="@drawable/text_color_select"
		android:textSize="@dimen/SP_SIZE_12" />

	<RadioButton
		android:id="@+id/RadioButton3"
		style="@style/fontStyle"
		android:layout_width="wrap_content"
		android:layout_height="28dp"
		android:layout_marginLeft="@dimen/SIZE_10"
		android:background="@drawable/bg_button_bg"
		android:button="@null"
		android:paddingLeft="@dimen/SIZE_10"
		android:paddingRight="@dimen/SIZE_10"
		android:text="@string/str_new_feature_suggestion"
		android:textColor="@drawable/text_color_select"
		android:textSize="@dimen/SP_SIZE_12" />

</RadioGroup>

<RadioGroup
	android:id="@+id/rgTow"
	android:layout_width="match_parent"
	android:layout_height="match_parent"
	android:layout_marginLeft="@dimen/SIZE_18"
	android:layout_marginRight="@dimen/SIZE_18"
	android:layout_marginBottom="@dimen/SIZE_20">

	<RadioButton
		android:id="@+id/RadioButton4"
		style="@style/fontStyle"
		android:layout_width="wrap_content"
		android:layout_height="28dp"
		android:layout_marginTop="@dimen/SIZE_9"
		android:background="@drawable/bg_button_bg"
		android:button="@null"
		android:paddingLeft="@dimen/SIZE_10"
		android:paddingRight="@dimen/SIZE_10"
		android:text="@string/str_type_other"
		android:textColor="@drawable/text_color_select"
		android:textSize="@dimen/SP_SIZE_12" />
</RadioGroup>

实现逻辑:

Kotlin 复制代码
private fun init(){
	mViewBind.rg.setOnCheckedChangeListener(OneCheckedChange())
    mViewBind.rgTow.setOnCheckedChangeListener(TowCheckedChange())
}

inner class OneCheckedChange : OnCheckedChangeListener {
	override fun onCheckedChanged(group: RadioGroup?, checkedId: Int) {
		// 清除另一RadioGroup选中状态
		mViewBind.rgTow.setOnCheckedChangeListener(null)
		mViewBind.rgTow.clearCheck()
		mViewBind.rgTow.setOnCheckedChangeListener(TowCheckedChange())
		// 根据 ID 判断选择的按钮
		mtype = when (checkedId) {
			R.id.RadioButton1 -> 1
			R.id.RadioButton2 -> 2
			R.id.RadioButton3 -> 3
			else -> 0
		}
	}

}

inner class TowCheckedChange : OnCheckedChangeListener{
	override fun onCheckedChanged(group: RadioGroup?, checkedId: Int) {
		mViewBind.rg.setOnCheckedChangeListener(null)
		mViewBind.rg.clearCheck()
		mViewBind.rg.setOnCheckedChangeListener(OneCheckedChange())
		// 根据 ID 判断选择的按钮
		if(checkedId == R.id.RadioButton4){
			mtype =4
		}
	}

}

至此实现【多个文本,多行显示,且同时只能选中一个】效果。

相关推荐
粤M温同学20 分钟前
Android Studio 有多个module,快速修改包名
android·android studio
学海无涯书山有路23 分钟前
Android LiveData + MVVM 新手入门教程(基于 XML+Java)
android·xml·java
晚霞的不甘25 分钟前
Flutter for OpenHarmony:注入灵魂:购物车的数据驱动与状态管理实战
android·前端·javascript·flutter·前端框架
福大大架构师每日一题26 分钟前
milvus v2.6.9 发布:支持主键搜索、段重开机制、日志性能全面提升!
android·java·milvus
_李小白1 小时前
【Android 美颜相机】第十六天:GPUImageTwoInputFilter 解析
android·数码相机
wy3136228211 小时前
android——Android Studio 路径迁移指南(释放 C 盘空间)
android·ide·android studio
L1624761 小时前
基于 Xenon 实现 MySQL 高可用集群(完整配置教程,含监控告警 + 定时备份)
android·mysql·adb
2501_916008891 小时前
无需钥匙串快速创建 iOS 开发 / 发布证书 P12 CSR
android·ios·小程序·https·uni-app·iphone·webview
学海无涯书山有路1 小时前
Android ViewBinding 新手详解(Java 版)—— 结合 ViewModel+LiveData 实战
android·java·开发语言
独自破碎E2 小时前
【快手手撕】合并区间
android·java