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
		}
	}

}

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

相关推荐
五彩小白10 小时前
自回归和上下文
android
事圆则缓12 小时前
Android 多渠道打包实战:Product Flavors、签名、AAB 与发包校验
android
树下困觉眯14 小时前
View绘制流程学习--获取WindowManager的三种方式
android·系统架构·view design
vilya15 小时前
我怎么给手机 GUI Agent 做双通道感知:无障碍树为主,投屏像素兜底
android·人工智能
李子红了时16 小时前
阿狸舞台APP(安卓端手机EncFS解密+压缩包解压+视频播放)
android·音视频
事圆则缓16 小时前
Android 使用 Jenkins 实现 CI/CD,并用 SonarQube 建立质量门禁
android·ci/cd·jenkins
其实防守也摸鱼16 小时前
DeepSeek Harness 开源贡献手记:从 Issue 到 Merge 的完整旅程
android·数据库·学习·ai·oracle·自动化
恋猫de小郭16 小时前
Android CLI 支持 AI Agent 通过 Device Streaming 调试云真机
android·前端·flutter
素师良码1 天前
第5篇:显示驱动必备调试工具浅析
android
维克兜率天1 天前
【维克】配对交易的季节性:哪些品种适合长拿?
android·开发语言·笔记·python·算法·kotlin·量化