探索RadioGroup下可否添加子Layout
2015-04-11 15:13
363 查看
创新杯的故事= =
阳光明媚的一天就这样开始了。
想写一个5*2的选择按钮,
用button,实现radiobutton的效果比较麻烦,而用radiobutton,写好之后发现radiogroup如果嵌套layout,就失去了他的功能。于是开始边寻思边折腾。
radiogroup明显是一个继承了viewgroup的layout,相信大家都看过下图,但他为何不能嵌套另一个viewgroup。。真是百思不得其姐。
(此处挠头半小时。)
我机智的决定去看android 的源码,
发现android自带的RadioGroup是继承自LinearLayout,如果布局的时候不是直接写radiobutton,即radiobutton外面还包了一层容器,这时分组是不成功的,因为查找不到radiobutton。
觉得问题在于addView方法和自定义的PassThroughHierarchyChangeListener,因为他们都是直接getchild来找radiobutton的。
下面就这两个地方动手脚,先拷贝源码,然后去掉
新增我们需要的方法用来查找viewGroup控件中的radioButton
能找到所有radiogroup下的radiobutton,剩下的就好办了。
等等。。。
写到这里我意识到了一个错误。。
对,就是这一行
wtf。。。他有一个index参数。。。而我们在自己的方法里找到的radiobutton并不能动态的分配给他index,也就是这样写应该显示是正常的。。但是如果你想添加个clicklistener估计就跪了,因为粑粑分不清他儿子在哪。
too young
改吧,
既然不能找一次返回多个radiobutton,那就一次返回一个吧。
ctrl+f 找到所有他需要radiobutton的地方 都要加else if 判断child是否是一个radiobutton,比如下边的OnHierarchyChangeListener
已经可以三百六十度无死角地不会unfortunately,yo
9ddf
ur lancher has stopped!
hhh,但是发现这么写缺点是 一个layout下只能包含一个radiobutton。
但是已经可以实现很多想要的布局了,比如
但是并不能满足我的需求。。
too naive
发觉此路不通。
换吧
(挠头半小时)
那不如我们自定义他子view的布局好了!!!
自定义view三宝:重载onMeasure(),onLayout(),onDraw()。
那我们就改他的onMeasure(),onLayout()。
其实上边挺费的。。就是拿一下childwidth和childheight,可能有的代码并没有用,改来改去也没删。重点是改子view:
快试试吧~~
好了,完美了~
余晖洒在旁边的同学吃完的橙子皮上
阳光明媚的一天就这样开始了。
想写一个5*2的选择按钮,
用button,实现radiobutton的效果比较麻烦,而用radiobutton,写好之后发现radiogroup如果嵌套layout,就失去了他的功能。于是开始边寻思边折腾。
radiogroup明显是一个继承了viewgroup的layout,相信大家都看过下图,但他为何不能嵌套另一个viewgroup。。真是百思不得其姐。
(此处挠头半小时。)
我机智的决定去看android 的源码,
发现android自带的RadioGroup是继承自LinearLayout,如果布局的时候不是直接写radiobutton,即radiobutton外面还包了一层容器,这时分组是不成功的,因为查找不到radiobutton。
觉得问题在于addView方法和自定义的PassThroughHierarchyChangeListener,因为他们都是直接getchild来找radiobutton的。
下面就这两个地方动手脚,先拷贝源码,然后去掉
RadioGroup(Context context, AttributeSet attrs)
新增我们需要的方法用来查找viewGroup控件中的radioButton
/** * @author Mr Seven * watch out ! view group can only have one layer of layout * @param group * @return */ public ArrayList<RadioButton> findRadioButton(ViewGroup group) { //find all child that is radiobutton ArrayList<RadioButton> btnList = new ArrayList<RadioButton>(); int len = group.getChildCount(); for (int i = 0; i < len; i++) { if (group.getChildAt(i) instanceof RadioButton) { btnList.add((RadioButton) group.getChildAt(i)); } else if (group.getChildAt(i) instanceof ViewGroup) { ArrayList<RadioButton> subList = findRadioButton((ViewGroup) group .getChildAt(i)); for (int j = 0; j < subList.size(); j++) { btnList.add(subList.get(j)); } } } return btnList; }
能找到所有radiogroup下的radiobutton,剩下的就好办了。
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); } //this block is new // child is a layout else if (child instanceof ViewGroup) { final ArrayList<RadioButton> buttonList = findRadioButton((ViewGroup) child); for(int i = 0 ; i < buttonList.size();i++){ final RadioButton button = buttonList.get(i); if (button.isChecked()) { mProtectFromCheckedChange = true; if (mCheckedId != -1) { setCheckedStateForView(mCheckedId, false); } mProtectFromCheckedChange = false; setCheckedId(button.getId()); } super.addView(button, index, params); }//for's circulation end } }
等等。。。
写到这里我意识到了一个错误。。
对,就是这一行
super.addView(button, index, params);
wtf。。。他有一个index参数。。。而我们在自己的方法里找到的radiobutton并不能动态的分配给他index,也就是这样写应该显示是正常的。。但是如果你想添加个clicklistener估计就跪了,因为粑粑分不清他儿子在哪。
too young
改吧,
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; }
既然不能找一次返回多个radiobutton,那就一次返回一个吧。
ctrl+f 找到所有他需要radiobutton的地方 都要加else if 判断child是否是一个radiobutton,比如下边的OnHierarchyChangeListener
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); } }
已经可以三百六十度无死角地不会unfortunately,yo
9ddf
ur lancher has stopped!
hhh,但是发现这么写缺点是 一个layout下只能包含一个radiobutton。
但是已经可以实现很多想要的布局了,比如
但是并不能满足我的需求。。
too naive
发觉此路不通。
换吧
(挠头半小时)
那不如我们自定义他子view的布局好了!!!
自定义view三宝:重载onMeasure(),onLayout(),onDraw()。
那我们就改他的onMeasure(),onLayout()。
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int maxWidth = MeasureSpec.getSize(widthMeasureSpec); int maxHeight = MeasureSpec.getSize(heightMeasureSpec); int childCount = getChildCount(); for (int index = 0; index < childCount; index++) { final View child = getChildAt(index); if (child.getVisibility() != View.GONE) { child.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); } } } // 设置容器所需的宽度和高度 setMeasuredDimension(maxWidth, maxHeight); parentHeight = maxHeight; parentWidth = maxWidth; childWidth = parentWidth/5; childHeight = parentHeight / 2; }
其实上边挺费的。。就是拿一下childwidth和childheight,可能有的代码并没有用,改来改去也没删。重点是改子view:
protected void onLayout(boolean changed, int l, int t, int r, int b) { final int childCount = getChildCount(); int maxWidth = r - l; int x = 0; int y = 0; int row = 0; for (int i = 0; i < childCount; i++) { final View child = this.getChildAt(i); if (child.getVisibility() != View.GONE) { // int width = child.getMeasuredWidth(); // int height = child.getMeasuredHeight(); int width = childWidth; int height = childHeight; x += width; y = row * height + height; if (i == 5) { x = width; row++; y = row * height + height; } child.layout(x - width, y - height, x, y); } } }
快试试吧~~
好了,完美了~
余晖洒在旁边的同学吃完的橙子皮上
相关文章推荐
- Android 代码中动态为RadioGroup添加RadioButton
- Android UI-实现底部切换标签之方式一 ──fragment(底部采用radioGroup+radiobutton)添加5个子fragment
- android自定义RadioGroup实现可以添加多种布局
- RadioGroup动态添加RadioButton,并且获得事件
- Ext的radiogroup动态添加radio
- RadioGroup自动添加RadioButton实现屏幕适配
- 动态添加RadioGroup组件的RadioButton出现多选状况解决
- Dialog中存在radiogroup动态添加radiobutton的ID问题
- RadioGroup动态添加RadioButton,RadioButton设置默认选中第一个,点击其他的RadioButton第一个不再选中,第一个不再选中
- android 动态添加组件(RadioGroup 添加RadioButton和其他组件的一些问题)
- android自定义RadioGroup实现可以添加多种布局
- Android RedioButton、RadioGroup底部添加动画位移横线下划线
- 仿QQ消息导航栏RadioGroup里添加拖拽的TextView(未读消息)
- Android的ListView中给RadioGroup添加setOnCheckChangeListener的问题之一
- RadioGroup - android自定义RadioGroup实现可以添加多种布局
- 自定义RadioGroup动态添加RadioButton,并获取选中radioButton的位置
- android自定义RadioGroup可以添加多种布局的实现方法
- android自定义RadioGroup实现可以添加多种布局
- RadioGroup中动态添加RadioButton,RadioButton状态紊乱
- Extjs中为RadioGroup组件添加监听事件,来控制另一个组件是否显示