我们都知道RadioGroup可以实现选择框,但它有一个局限性,由于它是继承自LinearLayout的,所以只能有一个方向,横向或者纵向;
好在我们可以自定义View来实现多行的一个RadioGroup(我把它命令为MultiLineRadioGroup);
在贴出代码之前,先来分析一下思路:
1、首先自定义一个View继承自ViewGroup,并且重写onMeasure方法和onLayout方法,分别用于测量Child尺寸和在ViewGroup中放置Child;
2、指定单个child元素,通过自定义属性的方式,由于要实现选择,即child是checkable的,我这里选择使用CheckBox作为child,使用的时候先在layout下指定一个xml文件并且设定它的根节点为CheckBox,然后把这个layout配置到MultiLineRadioGroup节点的child节点对应的属性中;
3、onMeasure方法中,我们只需要遍历ViewGroup的child并且调用measureChild方法对child进行测量;
4、onLayout方法中,我们根据child的尺寸来对child进行放置,具体来讲就是分别定义两个变量来记录上一个child的左上角Y坐标和右下角X坐标,并且根据当前要layout的child的尺寸进行是否需要换行的判断,如果当前要layout的child的宽度加上前一个View的右下角X坐标值大于当前MultiLineRadioGroup的宽度,则换行;摆放一个child完成之后需要对两个变量进行更新;
5、在onLayout的基础上,我们加入了child的水平间距和垂直间距的设置,通过自定义属性的方式;
6、在上面的基础上,对child进行统一化的管理,管理它的选择状态,以及添加、删除、选中一个child等常用方法;
再来预览一下程序界面效果图;
一、MultiLineRadioGroup.java
// org.ccflying.MultiLineRadioGroup
public class MultiLineRadioGroup extends ViewGroup implements OnClickListener {
private int mX, mY;
private List<CheckBox> viewList;
private int childMarginHorizontal = 0;
private int childMarginVertical = 0;
private int childResId = 0;
private int childCount = 0;
private int childValuesId = 0;
private boolean singleChoice = false;
private int mLastCheckedPosition = -1;
private OnCheckedChangedListener listener;
private List<String> childValues;
private boolean forceLayout;
public MultiLineRadioGroup(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
viewList = new ArrayList<CheckBox>();
childValues = new ArrayList<String>();
TypedArray arr = context.obtainStyledAttributes(attrs,
R.styleable.MultiLineRadioGroup);
childMarginHorizontal = arr.getDimensionPixelSize(
R.styleable.MultiLineRadioGroup_child_margin_horizontal, 15);
childMarginVertical = arr.getDimensionPixelSize(
R.styleable.MultiLineRadioGroup_child_margin_vertical, 5);
childResId = arr.getResourceId(
R.styleable.MultiLineRadioGroup_child_layout, 0);
childCount = arr.getInt(R.styleable.MultiLineRadioGroup_child_count, 0);
singleChoice = arr.getBoolean(
R.styleable.MultiLineRadioGroup_single_choice