Skip to content

Commit 710c7da

Browse files
committed
流式布局测量
1 parent daed1d6 commit 710c7da

File tree

1 file changed

+178
-3
lines changed

1 file changed

+178
-3
lines changed

app/src/main/java/com/example/lvruheng/autoflowlayout/AutoFlowLayout.java

Lines changed: 178 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,26 @@ public class AutoFlowLayout <T> extends LinearLayout {
7070
* 数据适配器
7171
*/
7272
private FlowAdapter<T> mAdapter;
73+
/**
74+
* 水平方向View之间的间距
75+
*/
76+
private int mHorizontalSpace;
77+
/**
78+
* 竖直方向View之间的间距
79+
*/
80+
private int mVerticalSpace;
81+
/**
82+
* 列数
83+
*/
84+
private int mColumnNumbers;
85+
/**
86+
* 行数
87+
*/
88+
private int mRowNumbers;
89+
/**
90+
* 是否设置了网格布局
91+
*/
92+
private boolean mIsGridMode;
7393

7494
public AutoFlowLayout(Context context) {
7595
super(context);
@@ -89,22 +109,100 @@ private void init(Context context, AttributeSet attrs) {
89109
mIsSingleLine = ta.getBoolean(R.styleable.AutoFlowLayout_singleLine,false);
90110
mMaxLineNumbers = ta.getInteger(R.styleable.AutoFlowLayout_maxLines,Integer.MAX_VALUE);
91111
mIsMultiChecked = ta.getBoolean(R.styleable.AutoFlowLayout_multiChecked,false);
112+
mHorizontalSpace = ta.getInteger(R.styleable.AutoFlowLayout_horizontalSpace,0);
113+
mVerticalSpace = ta.getInteger(R.styleable.AutoFlowLayout_verticalSpace,0);
114+
mColumnNumbers = ta.getInteger(R.styleable.AutoFlowLayout_columnNumbers,0);
115+
mRowNumbers = ta.getInteger(R.styleable.AutoFlowLayout_rowNumbers,0);
116+
if (mColumnNumbers != 0) {
117+
mIsGridMode = true;
118+
}
92119
ta.recycle();
93120
setOrientation(HORIZONTAL);
94121
}
95122
@Override
96123
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
97124
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
98-
setFlowMesure(widthMeasureSpec,heightMeasureSpec);
125+
if (mIsGridMode) {
126+
setGridMeasure(widthMeasureSpec,heightMeasureSpec);
127+
} else {
128+
setFlowMeasure(widthMeasureSpec,heightMeasureSpec);
129+
}
130+
131+
132+
}
99133

134+
/**
135+
* 网格布局的测量模式 默认各个子VIEW宽高值相同
136+
* @param widthMeasureSpec
137+
* @param heightMeasureSpec
138+
*/
139+
private void setGridMeasure(int widthMeasureSpec, int heightMeasureSpec) {
140+
// 获得它的父容器为它设置的测量模式和大小
141+
int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
142+
int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);
143+
int modeWidth = MeasureSpec.getMode(widthMeasureSpec);
144+
int modeHeight = MeasureSpec.getMode(heightMeasureSpec);
145+
//获取viewgroup的padding
146+
int paddingLeft = getPaddingLeft();
147+
int paddingRight = getPaddingRight();
148+
int paddingTop = getPaddingTop();
149+
int paddingBottom = getPaddingBottom();
150+
//超宽/超高纪录的最后值
151+
int lastHeight;
152+
int lastWidth;
153+
//最终的宽高值
154+
int heightResult;
155+
int widthResult;
156+
//未设置行数 推测行数
157+
if (mRowNumbers == 0) {
158+
mRowNumbers = getChildCount()/mColumnNumbers == 0 ?
159+
getChildCount()/mColumnNumbers : (getChildCount()/mColumnNumbers + 1);
160+
}
161+
int maxChildHeight = 0;
162+
int maxWidth = 0;
163+
int maxHeight = 0;
164+
//统计最大高度/最大宽度
165+
for (int i = 0; i < mRowNumbers; i++) {
166+
for (int j = 0; j < mColumnNumbers; j++) {
167+
final View child = getChildAt(i * mColumnNumbers + j);
168+
if (child != null) {
169+
if (child.getVisibility() != GONE) {
170+
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
171+
final int childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec, 0, lp.width);
172+
final int childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec, 0, lp.height);
173+
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
174+
maxWidth +=child.getMeasuredWidth();
175+
maxChildHeight = Math.max(maxChildHeight, child.getMeasuredHeight());
176+
}
177+
}
178+
}
179+
maxHeight += maxChildHeight;
180+
maxChildHeight = 0;
181+
}
182+
int tempWidth = maxWidth+mHorizontalSpace*(mColumnNumbers-1)+paddingLeft+paddingRight;
183+
int tempHeight = maxHeight+mVerticalSpace*(mRowNumbers-1)+paddingBottom+paddingTop;
184+
if (tempWidth > sizeWidth) {
185+
widthResult = sizeWidth;
186+
} else {
187+
widthResult = tempWidth;
188+
}
189+
//宽高超过屏幕大小,则进行压缩存放
190+
if (tempHeight > sizeHeight) {
191+
heightResult = sizeHeight;
192+
} else {
193+
heightResult = tempHeight;
194+
}
195+
setMeasuredDimension((modeWidth == MeasureSpec.EXACTLY) ? sizeWidth
196+
: widthResult, (modeHeight == MeasureSpec.EXACTLY) ? sizeHeight
197+
: heightResult);
100198
}
101199

102200
/**
103201
* 流式布局的测量模式
104202
* @param widthMeasureSpec
105203
* @param heightMeasureSpec
106204
*/
107-
private void setFlowMesure(int widthMeasureSpec, int heightMeasureSpec) {
205+
private void setFlowMeasure(int widthMeasureSpec, int heightMeasureSpec) {
108206
// 获得它的父容器为它设置的测量模式和大小
109207
int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
110208
int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);
@@ -178,7 +276,18 @@ private void setFlowMesure(int widthMeasureSpec, int heightMeasureSpec) {
178276

179277
@Override
180278
protected void onLayout(boolean changed, int l, int t, int r, int b) {
181-
setFlowLayout();
279+
if (mIsGridMode) {
280+
setGridLayout();
281+
} else {
282+
setFlowLayout();
283+
}
284+
}
285+
286+
/**
287+
* 网格布局的布局模式
288+
*/
289+
private void setGridLayout() {
290+
182291
}
183292

184293
/**
@@ -474,6 +583,72 @@ public void setAdapter(FlowAdapter<T> adapter) {
474583
}
475584
}
476585

586+
/**
587+
* 设置网格布局的水平间距
588+
* @param horizontalSpace 单位px
589+
*/
590+
public void setHorizontalSpace(int horizontalSpace) {
591+
mHorizontalSpace = horizontalSpace;
592+
requestLayout();
593+
}
594+
595+
/**
596+
* 返回网格布局的水平距离
597+
* @return
598+
*/
599+
public int getHorizontalSpace() {
600+
return mHorizontalSpace;
601+
}
602+
603+
/**
604+
* 设置网格布局的垂直间距
605+
* @param verticalSpace 单位px
606+
*/
607+
public void setVerticalSpace(int verticalSpace) {
608+
mVerticalSpace = verticalSpace;
609+
requestLayout();
610+
}
611+
612+
/**
613+
* 返回网格布局的垂直距离
614+
*/
615+
public int getVerticalSpace() {
616+
return mVerticalSpace;
617+
}
618+
619+
/**
620+
* 设置列数
621+
* @param columnNumbers
622+
*/
623+
public void setColumnNumbers(int columnNumbers) {
624+
mColumnNumbers = columnNumbers;
625+
}
626+
627+
/**
628+
* 获得列数
629+
* @return
630+
*/
631+
public int getColumnNumbers() {
632+
return mColumnNumbers;
633+
}
634+
635+
/**
636+
* 设置行数
637+
* @param rowNumbers
638+
*/
639+
public void setRowNumbers(int rowNumbers) {
640+
mRowNumbers = rowNumbers;
641+
}
642+
643+
/**
644+
* 得到行数
645+
* @return
646+
*/
647+
public int getRowNumbers() {
648+
return mRowNumbers;
649+
}
650+
651+
477652
public interface OnItemClickListener{
478653
void onItemClick(int position,View view);
479654
}

0 commit comments

Comments
 (0)