公司项目最近有个这样的需求,要求实现【多个文本,多行显示,且同时只能选中一个】。设计图效果如下:
看上去很简单,使用 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
}
}
}
至此实现【多个文本,多行显示,且同时只能选中一个】效果。