項目源碼地址: https://github.com/angcyo/FlowRadioGroup
為了更好的擁有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();//行數(shù)
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 , 中已經(jīng)加在了 lineHeight 中
child.layout(ld, td, rd, bd);
left += child.getMeasuredWidth() + params.leftMargin + params.rightMargin;//因為在 這里添加了;
}
left = getPaddingLeft();
top += lineHeight;
}
}
到此,基本上布局就可以使用了;
不過還有一個問題,就是布局不具備保存狀態(tài)的能力;
所以需要重寫onSaveInstanceState和onRestoreInstanceState方法;
這里不展示,項目源碼中有,并且也有使用方法;
為了更靈活, 更方便使用;
可以擴張接口;
/**
* 獲取選中按鈕的索引,從開始, 未選中返回 -1
*/
public int getCheckedRadioButtonIndex() {
return indexOfChild(findViewById(getCheckedRadioButtonId()));
}
/**
* 獲取選中按鈕的文本,未選中 返回 空字符串
*/
public String getCheckedRadioButtonText() {
if (getCheckedRadioButtonId() == -1) {
return "";
}
return ((RadioButton) findViewById(getCheckedRadioButtonId())).getText().toString();
}
更多更好的擴展方法, 大家可以根據(jù)需求定制;
至此: 文章就結(jié)束了,如有疑問: QQ群:274306954 歡迎您的加入.