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

}

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

相关推荐
百锦再4 小时前
第11章 泛型、trait与生命周期
android·网络·人工智能·python·golang·rust·go
会跑的兔子5 小时前
Android 16 Kotlin协程 第二部分
android·windows·kotlin
键来大师5 小时前
Android15 RK3588 修改默认不锁屏不休眠
android·java·framework·rk3588
江上清风山间明月8 小时前
Android 系统超级实用的分析调试命令
android·内存·调试·dumpsys
百锦再8 小时前
第12章 测试编写
android·java·开发语言·python·rust·go·erlang
用户693717500138412 小时前
Kotlin 协程基础入门系列:从概念到实战
android·后端·kotlin
SHEN_ZIYUAN12 小时前
Android 主线程性能优化实战:从 90% 降至 13%
android·cpu优化
曹绍华12 小时前
android 线程loop
android·java·开发语言
雨白12 小时前
Hilt 入门指南:从 DI 原理到核心用法
android·android jetpack
介一安全12 小时前
【Frida Android】实战篇3:基于 OkHttp 库的 Hook 抓包
android·okhttp·网络安全·frida