自定义多行多列的RadioGroup
来源:互联网 发布:先锋网络电视免费版 编辑:程序博客网 时间:2024/05/16 19:10
最近在工作的时候,需要用到一个多行多列的radioGroup,在网上找资料的时候,又找不掉合适的,所以只好自己写一个,同时也个那些需要这个功能的人一些参考;首先,我先分析了一下,我需要的仅仅是一个可以多行多列显示的控件,但是radioGroup却只有横向和纵向,并不支持换行,最近刚刚好看了一些自定义控件的内容,因此,想想可以自己定义一个控件,当然,还是要继承自radioGroup,这样可以节省很多的功能;剩下的,做的就是重写onMeasure和onLayout两个方法,来对子控件进行排列,实现多行效果,先上张图:
这是简单的效果图,控件的宽度是子控件自己决定的
该上关键代码啦
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int height = 0; if (getChildCount() > 0) { startX = 0; //父控件高度 rowNm = 0; for (int i = 0; i < getChildCount(); i++) { RadioButton rb = (RadioButton) getChildAt(i); //测量子控件 measureChild(rb, widthMeasureSpec, heightMeasureSpec); //子控件宽度+起始位置坐标,如果大于父控件高度,就换行 int w = rb.getMeasuredWidth() + 2 * childMarginHorizontal + startX + getPaddingLeft() + getPaddingRight(); if (w > getMeasuredWidth()) { startX = 0; rowNm++; } //否则起始位置后移 startX += rb.getMeasuredWidth() + 2 * childMarginHorizontal; height = (rowNm + 1) * (rb.getMeasuredHeight() + 2 * childMarginVertical) + getPaddingBottom() + getPaddingTop(); } } JLog.i(startX + "测量的高度" + height); setMeasuredDimension(getMeasuredWidth(), height); }
Layout方法,还是很详细的注释
@Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); startX = 0; startY = 0; rowNm = 0; for (int i = 0; i < getChildCount(); i++) { RadioButton rb = (RadioButton) getChildAt(i); int w = rb.getMeasuredWidth() + 2 * childMarginHorizontal + startX + getPaddingLeft() + getPaddingRight(); if (w > getMeasuredWidth()) { startX = 0; rowNm++; } startY = rowNm * (rb.getMeasuredHeight() + 2 * childMarginVertical); JLog.i("=====onLayout=====" + startX + "===" + rowNm + "==" + startY); //绘制每个子控件的位置 rb.layout(startX, startY, startX + rb.getMeasuredWidth(), startY + rb.getMeasuredHeight()); startX += rb.getMeasuredWidth() + 2 * childMarginHorizontal; } }
好了,关键代码还是很简单的,这下自己就不用再麻烦的找了,自己写一个就好了,而且十分好用啊;现在上全部代码吧,是分简单
public class CustomRadioGoup extends RadioGroup { private int startX = 0, startY = 0, rowNm = 0; private List<String> childs = new ArrayList<>(); private int childId =-1; /** * 横向间距 */ private int childMarginHorizontal = 10; /** * 纵向间距 */ private int childMarginVertical = 10; public CustomRadioGoup(Context context) { super(context); } public CustomRadioGoup(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int height = 0; if (getChildCount() > 0) { startX = 0; //父控件高度 rowNm = 0; for (int i = 0; i < getChildCount(); i++) { RadioButton rb = (RadioButton) getChildAt(i); //测量子控件 measureChild(rb, widthMeasureSpec, heightMeasureSpec); //子控件宽度+起始位置坐标,如果大于父控件高度,就换行 int w = rb.getMeasuredWidth() + 2 * childMarginHorizontal + startX + getPaddingLeft() + getPaddingRight(); if (w > getMeasuredWidth()) { startX = 0; rowNm++; } //否则起始位置后移 startX += rb.getMeasuredWidth() + 2 * childMarginHorizontal; height = (rowNm + 1) * (rb.getMeasuredHeight() + 2 * childMarginVertical) + getPaddingBottom() + getPaddingTop(); } } JLog.i(startX + "测量的高度" + height); setMeasuredDimension(getMeasuredWidth(), height); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); startX = 0; startY = 0; rowNm = 0; for (int i = 0; i < getChildCount(); i++) { RadioButton rb = (RadioButton) getChildAt(i); int w = rb.getMeasuredWidth() + 2 * childMarginHorizontal + startX + getPaddingLeft() + getPaddingRight(); if (w > getMeasuredWidth()) { startX = 0; rowNm++; } startY = rowNm * (rb.getMeasuredHeight() + 2 * childMarginVertical); JLog.i("=====onLayout=====" + startX + "===" + rowNm + "==" + startY); //绘制每个子控件的位置 rb.layout(startX, startY, startX + rb.getMeasuredWidth(), startY + rb.getMeasuredHeight()); startX += rb.getMeasuredWidth() + 2 * childMarginHorizontal; } } private RadioButton getChild() { if (childId==-1){ throw new RuntimeException("没有设置子控件"); } return (RadioButton) LayoutInflater.from(getContext()).inflate( R.layout.item, this, false); } /** * 设置子控件,最好为根节点为RadioButton 的layout * @param layout_id 子控件的Id */ public void setChild(int layout_id){ this.childId=layout_id; } /** * 添加一个名字为str的控件 * @param str */ public void addView(String str) { childs.add(str); RadioButton child = getChild(); child.setText(str); addView(child); postInvalidate(); }}
最后,使用的时候子控件传进去的必须是一个layout文件的,根节点是radioButton最好了,样式自己定义就好了,如果宽高固定,那子控件就是大小相同的,否则就是我上传的图片的效果;
在给个子控件布局吧
<?xml version="1.0" encoding="utf-8"?><RadioButton xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#fedcba" android:text="测试"></RadioButton>
0 2
- 自定义多行多列的RadioGroup
- 支持自定义布局的RadioGroup
- 自定义横向的RadioGroup:HorizontalRadioGroup
- 自定义RadioGroup实现radioButton多行多列
- 自定义的radioGroup和自定义的editText
- 自定义:RadioGroup
- RadioGroup以及RadioButton自定义样式的使用
- 自定义支持多行显示的RadioGroup
- Android RadioGroup 自定义布局, 支持多行多列
- Android RadioGroup 自定义布局, 支持多行多列
- IOS自定义RadioGroup
- Android 自定义RadioGroup布局
- 自定义添加多列多行radioGroup
- Android自定义RadioGroup
- 自定义RadioGroup样式
- 自定义RadioGroup 实现选择
- Android.自定义控件的实现_RadioButton 和RadioGroup
- 【Android自定义控件】支持多层嵌套RadioButton的RadioGroup
- KMP算法
- 关于oracle的监听响应速度过慢
- MySQL 开启FEDERATED 引擎
- u3d shader入门写法
- haskell之Functor、Applicative、Monad
- 自定义多行多列的RadioGroup
- 经典算法心得
- 小小冒泡法
- Handler,Looper,Message,MessageQueue,HandlerThread使用总结(上)
- 5.12
- Excel技巧
- 顺序表应用1:多余元素删除之移位算法
- css3实现隔行换色
- eclipse背景色及字体色等的设置方法和样例