android自定义RadioGroup可以添加多种布局的实现方法

时间:2021-05-20

android自带的RadioGroup是继承自LinearLayout,如果布局的时候不是直接写radiobutton,即radiobutton外面还包了一层容器,这时分组是不成功的,因为查找不到radiobutton,如果要实现这种效果呢,于是看了RadioGroup的源码,发现问题在于addView方法和自定义的PassThroughHierarchyChangeListener;

下面就这两个地方动手脚,先拷贝源码,然后去掉RadioGroup(Context context, AttributeSet attrs) 中的方法,我新增了一个方法,查找viewGroup控件中的radioButton
复制代码 代码如下:
/** 查找radioButton控件 */
public RadioButton findRadioButton(ViewGroup group) {
RadioButton resBtn = null;
int len = group.getChildCount();
for (int i = 0; i < len; i++) {
if (group.getChildAt(i) instanceof RadioButton) {
resBtn = (RadioButton) group.getChildAt(i);
} else if (group.getChildAt(i) instanceof ViewGroup) {
findRadioButton((ViewGroup) group.getChildAt(i));
}
}
return resBtn;
}

addView的实现如下:

复制代码 代码如下:
@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());
}
} else if (child instanceof ViewGroup) { //这里是我添加的代码
final RadioButton button = findRadioButton((ViewGroup) child);
if (button.isChecked()) {
mProtectFromCheckedChange = true;
if (mCheckedId != -1) {
setCheckedStateForView(mCheckedId, false);
}
mProtectFromCheckedChange = false;
setCheckedId(button.getId());
}
}

super.addView(child, index, params);
}

然后在自定义的PassThroughHierarchyChangeListener中修改:
复制代码 代码如下:
private class PassThroughHierarchyChangeListener implements
ViewGroup.OnHierarchyChangeListener {
private ViewGroup.OnHierarchyChangeListener mOnHierarchyChangeListener;

public void onChildViewAdded(View parent, View child) {
if (parent == MyRadioGroup.this && child instanceof RadioButton) {
int id = child.getId();
// generates an id if it's missing
if (id == View.NO_ID) {
id = child.hashCode();
child.setId(id);
}
((RadioButton) child)
.setOnCheckedChangeListener(mChildOnCheckedChangeListener);
} else if (parent == MyRadioGroup.this //这里是我添加的代码
&& child instanceof ViewGroup) {
RadioButton btn = findRadioButton((ViewGroup) child);
int id = btn.getId();
// generates an id if it's missing
if (id == View.NO_ID) {
id = btn.hashCode();
btn.setId(id);
}
btn.setOnCheckedChangeListener(mChildOnCheckedChangeListener);
}

if (mOnHierarchyChangeListener != null) {
mOnHierarchyChangeListener.onChildViewAdded(parent, child);
}
}

public void onChildViewRemoved(View parent, View child) {
if (parent == MyRadioGroup.this && child instanceof RadioButton) {
((RadioButton) child).setOnCheckedChangeListener(null);
} else if (parent == MyRadioGroup.this
&& child instanceof ViewGroup) {
findRadioButton((ViewGroup) child).setOnCheckedChangeListener(
null);
}
if (mOnHierarchyChangeListener != null) {
mOnHierarchyChangeListener.onChildViewRemoved(parent, child);
}
}
}

做好了上面的步骤,下面布局就可以按照自己的意思来了,并且分组效果也不会影响

下面我的布局文件demo:
复制代码 代码如下:
<com.huaheng.wy.view.MyRadioGroup
android:id="@+id/rg"
android:layout_width="fill_parent"
android:layout_height="65dp"
android:layout_alignParentBottom="true"
android:background="@drawable/yst_i_bottom"
android:orientation="horizontal" >

<!-- 首页 -->

<FrameLayout
android:id="@+id/left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginBottom="2dp"
android:layout_marginTop="3dp"
android:layout_weight="1" >

<RadioButton
android:id="@+id/rbtn_home"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@null"
android:button="@null"
android:drawableTop="@drawable/yst_i_bottomhome_selector"
android:gravity="center_horizontal"
android:text="首页"
android:textColor="@color/white"
android:textSize="@dimen/font_5" />

<Button
android:id="@+id/btn_home_point"
android:layout_width="21dp"
android:layout_height="20dp"
android:layout_gravity="top|right"
android:layout_marginRight="10dp"
android:layout_marginTop="0dp"
android:background="@drawable/notice_bg"
android:text="1"
android:textColor="@color/white"
android:textSize="@dimen/font_6"
android:visibility="gone" />
</FrameLayout>
<!-- 历史 -->

<RadioButton
android:id="@+id/rbtn_his"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginBottom="2dp"
android:layout_marginTop="3dp"
android:layout_weight="1"
android:background="@null"
android:button="@null"
android:drawableTop="@drawable/yst_i_bottomhis_selector"
android:gravity="center_horizontal"
android:text="历史"
android:textColor="@color/white"
android:textSize="@dimen/font_5" />

<!-- 扫描 -->

<Button
android:id="@+id/rbtn_scan"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="@drawable/scan_selector"
android:button="@null"
android:gravity="center_horizontal|bottom"
android:paddingBottom="7dp"
android:text="扫描"
android:textColor="@color/white"
android:textSize="@dimen/font_5" />

<RadioButton
android:id="@+id/rbtn_seek"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginBottom="2dp"
android:layout_marginTop="3dp"
android:layout_weight="1"
android:background="@null"
android:button="@null"
android:drawableTop="@drawable/yst_i_bottomseek_selector"
android:gravity="center_horizontal"
android:text="搜索"
android:textColor="@color/white"
android:textSize="@dimen/font_5" />

<RadioButton
android:id="@+id/rbtn_more"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginBottom="2dp"
android:layout_marginTop="3dp"
android:layout_weight="1"
android:background="@null"
android:button="@null"
android:drawableTop="@drawable/yst_i_bottommore_selector"
android:gravity="center_horizontal"
android:text="更多"
android:textColor="@color/white"
android:textSize="@dimen/font_5" />
</com.huaheng.wy.view.MyRadioGroup>

所有实现代码都在这里,下面我就把自定义的radioGroup的代码,完整的贴出来
复制代码 代码如下:
/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://poundButton buttonView,
boolean isChecked) {
// prevents from infinite recursion
if (mProtectFromCheckedChange) {
return;
}

mProtectFromCheckedChange = true;
if (mCheckedId != -1) {
setCheckedStateForView(mCheckedId, false);
}
mProtectFromCheckedChange = false;

int id = buttonView.getId();
setCheckedId(id);
}
}

/**
* <p>
* A pass-through listener acts upon the events and dispatches them to
* another listener. This allows the table layout to set its own internal
* hierarchy change listener without preventing the user to setup his.
* </p>
*/
private class PassThroughHierarchyChangeListener implements
ViewGroup.OnHierarchyChangeListener {
private ViewGroup.OnHierarchyChangeListener mOnHierarchyChangeListener;

public void onChildViewAdded(View parent, View child) {
if (parent == MyRadioGroup.this && child instanceof RadioButton) {
int id = child.getId();
// generates an id if it's missing
if (id == View.NO_ID) {
id = child.hashCode();
child.setId(id);
}
((RadioButton) child)
.setOnCheckedChangeListener(mChildOnCheckedChangeListener);
} else if (parent == MyRadioGroup.this
&& child instanceof ViewGroup) {
RadioButton btn = findRadioButton((ViewGroup) child);
int id = btn.getId();
// generates an id if it's missing
if (id == View.NO_ID) {
id = btn.hashCode();
btn.setId(id);
}
btn.setOnCheckedChangeListener(mChildOnCheckedChangeListener);
}

if (mOnHierarchyChangeListener != null) {
mOnHierarchyChangeListener.onChildViewAdded(parent, child);
}
}

public void onChildViewRemoved(View parent, View child) {
if (parent == MyRadioGroup.this && child instanceof RadioButton) {
((RadioButton) child).setOnCheckedChangeListener(null);
} else if (parent == MyRadioGroup.this
&& child instanceof ViewGroup) {
findRadioButton((ViewGroup) child).setOnCheckedChangeListener(
null);
}
if (mOnHierarchyChangeListener != null) {
mOnHierarchyChangeListener.onChildViewRemoved(parent, child);
}
}
}
}

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章