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

看上去很简单,使用 RadioGroup + LinearLayout + RadioButton 快速实现:
- <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源码:
- @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的选中效果,代码如下:
- <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>
实现逻辑:
- 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
- }
- }
-
- }
至此实现【多个文本,多行显示,且同时只能选中一个】效果。