Android RadioGroup流式布局及动态添加RadioButton

RadioGroup流式布局

Android开发商城应用中会遇到商品属性标签的选择,可以使用自定义RadioGroup流式布局实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
public class FlowRadioGroup extends RadioGroup {

private static final String TAG = FlowRadioGroup.class.getSimpleName();

public FlowRadioGroup(Context context) {
super(context);
}

public FlowRadioGroup(Context context, AttributeSet attrs) {
super(context, attrs);
}

@Override
protected LinearLayout.LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) {
return new LinearLayout.LayoutParams(lp);
}

@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new LayoutParams(getContext(), attrs);
}

@Override
protected LinearLayout.LayoutParams generateDefaultLayoutParams() {
return new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
}

/**
* 负责设置子控件的测量模式和大小 根据所有子控件设置自己的宽和高
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// 获得它的父容器为它设置的测量模式和大小
int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);
int modeWidth = MeasureSpec.getMode(widthMeasureSpec);
int modeHeight = MeasureSpec.getMode(heightMeasureSpec);

Log.e(TAG, sizeWidth + ", " + sizeHeight);

// 如果是warp_content情况下,记录宽和高
int width = 0;
int height = 0;
/**
* 记录每一行的宽度,width不断取最大宽度
*/
int lineWidth = 0;
/**
* 每一行的高度,累加至height
*/
int lineHeight = 0;

int cCount = getChildCount();
NLog.i("yezhou", "onMeasure child count: " + cCount);

// 遍历每个子元素
for (int i = 0; i < cCount; i++) {
View child = getChildAt(i);
// 测量每一个child的宽和高
measureChild(child, widthMeasureSpec, heightMeasureSpec);
// 得到child的lp
MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
// 当前子空间实际占据的宽度
int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
// 当前子空间实际占据的高度
int childHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;

if (mFlowMode) {
/**
* 如果加入当前child,则超出最大宽度,则的到目前最大宽度给width,类加height 然后开启新行
*/
if (lineWidth + childWidth > sizeWidth) {
width = Math.max(lineWidth, childWidth);// 取最大的
lineWidth = childWidth; // 重新开启新行,开始记录
// 叠加当前高度,
height += lineHeight;
// 开启记录下一行的高度
lineHeight = childHeight;
} else
// 否则累加值lineWidth,lineHeight取最大高度
{
lineWidth += childWidth;
lineHeight = Math.max(lineHeight, childHeight);
}
// 如果是最后一个,则将当前记录的最大宽度和当前lineWidth做比较
if (i == cCount - 1) {
width = Math.max(width, lineWidth);
height += lineHeight;
}

} else {
/**
* 如果加入当前child,则超出最大高度,则的到目前最大高度给height,累加width 然后开启新列
*/
if (lineHeight + childHeight > sizeHeight) {
height = Math.max(lineHeight, childHeight);// 取最大的
lineHeight = childHeight; // 重新开启新行,开始记录
// 叠加当前高度,
width += lineWidth;
// 开启记录下一行的高度
lineWidth = childWidth;
} else
// 否则累加值lineHeight,lineWidth取最大高度
{
lineHeight += childHeight;
lineWidth = Math.max(lineWidth, childWidth);
}
// 如果是最后一个,则将当前记录的最大高度和当前lineHeight做比较
if (i == cCount - 1) {
height = Math.max(height, lineHeight);
width += lineWidth;
}
}

}
setMeasuredDimension((modeWidth == MeasureSpec.EXACTLY) ? sizeWidth : width, (modeHeight == MeasureSpec.EXACTLY) ? sizeHeight : height);
}

/**
* 存储所有的View,按行记录
*/
private List<List<View>> mAllViews = new ArrayList<List<View>>();
/**
* 记录每一行的最大高度
*/
private List<Integer> mLineHeight = new ArrayList<Integer>();
/**
* 记录每一列的最大宽度
*/
private List<Integer> mLineWidth = new ArrayList<Integer>();

private void setFlowMode(boolean flowMode) {
mFlowMode = flowMode;
}

boolean mFlowMode = true;

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
mAllViews.clear();
if (mFlowMode) {
mLineHeight.clear();
} else {
mLineWidth.clear();
}

int width = getWidth();
int height = getHeight();

int lineWidth = 0;
int lineHeight = 0;
// 存储每一行所有的childView
List<View> lineViews = new ArrayList<View>();
int cCount = getChildCount();
NLog.i("yezhou", "onMeasure child count: " + cCount);

// 遍历所有的孩子
for (int i = 0; i < cCount; i++) {
View child = getChildAt(i);
MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
int childWidth = child.getMeasuredWidth();
int childHeight = child.getMeasuredHeight();

// 如果已经需要换行
if (childWidth + lp.leftMargin + lp.rightMargin + lineWidth > width) {
// 记录这一行所有的View以及最大高度
mLineHeight.add(lineHeight);
// 将当前行的childView保存,然后开启新的ArrayList保存下一行的childView
mAllViews.add(lineViews);
lineWidth = 0;// 重置行宽
lineViews = new ArrayList<View>();
}

/**
* 如果不需要换行,则累加
*/
lineWidth += childWidth + lp.leftMargin + lp.rightMargin;
lineHeight = Math.max(lineHeight, childHeight + lp.topMargin + lp.bottomMargin);
lineViews.add(child);
}

// 记录最后一行
mLineHeight.add(lineHeight);
mAllViews.add(lineViews);
int left = 0;
int top = 0;
// 得到总行数
int lineNums = mAllViews.size();
for (int i = 0; i < lineNums; i++) {
// 每一行的所有的views
lineViews = mAllViews.get(i);
// 当前行的最大高度
lineHeight = mLineHeight.get(i);
// 遍历当前行所有的View
for (int j = 0; j < lineViews.size(); j++) {
View child = lineViews.get(j);
if (child.getVisibility() == View.GONE) {
continue;
}
MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();

// 计算childView的left,top,right,bottom
int lc = left + lp.leftMargin;
int tc = top + lp.topMargin;
int rc = lc + child.getMeasuredWidth();
int bc = tc + child.getMeasuredHeight();
child.layout(lc, tc, rc, bc);

left += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
}
left = 0;
top += lineHeight;
}
}

@Override
public void addView(View child) {
super.addView(child);
requestLayout();
invalidate();
}

@Override
public void addView(View child, int index) {
super.addView(child, index);
requestLayout();
invalidate();
}
}

动态添加RadioButton

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public void onBindViewHolder(final ViewHolder holder, final int position) {
final GoodsOption goodsOption = mGoodsOptionList.get(position);
holder.tvOptionName.setText(goodsOption.getOptName());
List<GoodsOption.OptionValue> optionValueList = goodsOption.getOptionValueList();
if (optionValueList != null && optionValueList.size() > 0) {
final int defaultFontColor = mContext.getResources().getColor(R.color.textPrimaryMedium);
for (GoodsOption.OptionValue optionValue : optionValueList) {
RadioButton radioButton = new RadioButton(mContext);
radioButton.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12);
RadioGroup.LayoutParams layoutParams = new RadioGroup.LayoutParams(ViewGroup.MarginLayoutParams.WRAP_CONTENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT);
layoutParams.setMargins(0, 0, DisplayUtil.dp2px(5), 0);
radioButton.setLayoutParams(layoutParams);
radioButton.setText(optionValue.getOptValueName());
radioButton.setBackgroundResource(R.drawable.selector_text_rect);
radioButton.setButtonDrawable(null);
radioButton.setTextColor(defaultFontColor);
radioButton.setPadding(DisplayUtil.dp2px(8), DisplayUtil.dp2px(3), DisplayUtil.dp2px(8), DisplayUtil.dp2px(3));
holder.flowRadioGroupAttr.addView(radioButton);
}
holder.flowRadioGroupAttr.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup radioGroup, int position) {
int childCount = radioGroup.getChildCount();
RadioButton radioButton;
for (int i = 0; i < childCount; i++) {
radioButton = (RadioButton) radioGroup.getChildAt(i);
if (radioButton.isChecked()) {
radioButton.setTextColor(Color.WHITE);
} else {
radioButton.setTextColor(defaultFontColor);
}
}
}
});
((RadioButton) holder.flowRadioGroupAttr.getChildAt(0)).setChecked(true);
}
}

Powered by AppBlog.CN     浙ICP备14037229号

Copyright © 2012 - 2020 APP开发技术博客 All Rights Reserved.

访客数 : | 访问量 :