Android-->FlowRadioGroup(流式布局RadioGroup, 自定义View的简单使用)

项目源码地

为了更好的拥有RadioGroup的属性/方法:
1:新建一个View,继承RadioGroup

public class FlowRadioGroup extends RadioGroup

流式布局最重要的就是,测量子View 的大小和子View 的布局位置
2:重写onMeasure和onLayout方法

List<List<View>> mAllViews;//保存所有行的所有View
List<Integer> mLineHeight;//保存每一行的行高

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
    int modeWidth = MeasureSpec.getMode(widthMeasureSpec);
    int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);
    int modeHeight = MeasureSpec.getMode(heightMeasureSpec);

    int width = 0, height = 0;
    int lineWidth = 0, lineHeight = 0;
    int childWidth = 0, childHeight = 0;

    mAllViews = new ArrayList<>();
    mLineHeight = new ArrayList<>();

    List<View> lineViews = new ArrayList<>();
    int count = getChildCount();
    for (int i = 0; i < count; i++) {
        View child = getChildAt(i);
        measureChild(child, widthMeasureSpec, heightMeasureSpec);
        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) child.getLayoutParams();

        childWidth = child.getMeasuredWidth() + params.leftMargin + params.rightMargin;
        childHeight = child.getMeasuredHeight() + params.topMargin + params.bottomMargin;

        if (lineWidth + childWidth > sizeWidth - getPaddingLeft() - getPaddingRight()) {
            width = Math.max(width, lineWidth);
            height += lineHeight;
            mLineHeight.add(lineHeight);
            mAllViews.add(lineViews);

            lineWidth = childWidth;
            lineHeight = childHeight;
            lineViews = new ArrayList<>();
        } else {
            lineWidth += childWidth;
            lineHeight = Math.max(childHeight, lineHeight);
        }
        lineViews.add(child);

        if (i == (count - 1)) {
            width = Math.max(width, lineWidth);
            height += lineHeight;
        }
    }
    mLineHeight.add(lineHeight);
    mAllViews.add(lineViews);
    width += getPaddingLeft() + getPaddingRight();
    height += getPaddingTop() + getPaddingBottom();
    setMeasuredDimension(modeWidth == MeasureSpec.AT_MOST ? width : sizeWidth, modeHeight == MeasureSpec.AT_MOST ? height : sizeHeight);
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    int top = getPaddingTop();//开始布局子view的 top距离
    int left = getPaddingLeft();//开始布局子view的 left距离

    int lineNum = mAllViews.size();//行数
    List<View> lineView;
    int lineHeight;
    for (int i = 0; i < lineNum; i++) {
        lineView = mAllViews.get(i);
        lineHeight = mLineHeight.get(i);

        for (int j = 0; j < lineView.size(); j++) {
            View child = lineView.get(j);
            if (child.getVisibility() == View.GONE) {
                continue;
            }

            LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) child.getLayoutParams();
            int ld = left + params.leftMargin;
            int td = top + params.topMargin;
            int rd = ld + child.getMeasuredWidth();//不需要加上 params.rightMargin,
            int bd = td + child.getMeasuredHeight();//不需要加上 params.bottomMargin, 因为在 onMeasure , 中已经加在了 lineHeight 中
            child.layout(ld, td, rd, bd);

            left += child.getMeasuredWidth() + params.leftMargin + params.rightMargin;//因为在 这里添加了;
        }

        left = getPaddingLeft();
        top += lineHeight;
    }
}

到此,基本上布局就可以使用了;
不过还有一个问题,就是布局不具备保存状态的能力;
所以需要重写onSaveInstanceState和onRestoreInstanceState方法;
这里不展示,项目源码中有,并且也有使用方法;


为了更灵活, 更方便使用;
可以扩张接口;

/**
 * 获取选中按钮的索引,从开始, 未选中返回 -1
 */
public int getCheckedRadioButtonIndex() {
    return indexOfChild(findViewById(getCheckedRadioButtonId()));
}

/**
 * 获取选中按钮的文本,未选中 返回 空字符串
 */
public String getCheckedRadioButtonText() {
    if (getCheckedRadioButtonId() == -1) {
        return "";
    }
    return ((RadioButton) findViewById(getCheckedRadioButtonId())).getText().toString();
}

更多更好的扩展方法, 大家可以根据需求定制;


至此: 文章就结束了,如有疑问: QQ群:274306954 欢迎您的加入.



作者:angcyo
链接:https://www.jianshu.com/p/e49aaaa6c10f
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

地址: https://github.com/angcyo/FlowRadioGroup

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值