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

}

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

相关推荐
星间都市山脉1 小时前
Android16 SystemService.onBootPhase 调用时机
android·java·linux·windows·ubuntu
swithun1 小时前
不用 WebView,我用 Kotlin + Compose Multiplatform 重写 Mermaid,并做了 2048 组对拍
android·开源·kotlin
AI吃大瓜1 小时前
人脸检测和行人检测4:Android实现YOLOv8 YOLO11 YOLO26人脸检测和人体检测(含源码,可实时检测)
android·yolo·人脸检测·人体检测·行人检测·yolo26
与海boy1 小时前
Prompt模版
android·prompt
FlightYe2 小时前
音视频修炼之编码器(一):AVC、HEVC编码器内部
android·linux·c++·音视频
智购科技无人售货机工厂2 小时前
2026自动售货机AI智能体架构:从47个小模型到33.7亿Token的工程实践~YH
android·人工智能·驱动开发·单片机·pandas
嵩风抚3 小时前
一款HK银行APP的业务+技术
android·flutter·react native·html5
00后程序员张5 小时前
怎么用 Egret(白鹭引擎)打包 iOS 应用并上架 App Store?
android·ios·小程序·https·uni-app·iphone·webview
mmsx5 小时前
MapLibre 实战 09|Bug 单写着"地图被风刮走了":一个瓦片源工厂,是三个线上事故换来的
android·前端·开源
一技安身5 小时前
【信创】统信UOS 银河麒麟离线部署Python3.11完整方案
android·java·python3.11