package
com.zhy.zhy_flowlayout02;
import
java.util.ArrayList;
import
java.util.List;
import
android.content.Context;
import
android.util.AttributeSet;
import
android.util.Log;
import
android.view.View;
import
android.view.ViewGroup;
public
class
FlowLayout
extends
ViewGroup
{
private
static
final
String TAG =
"FlowLayout"
;
public
FlowLayout(Context context, AttributeSet attrs)
{
super
(context, attrs);
}
@Override
protected
ViewGroup.LayoutParams generateLayoutParams(
ViewGroup.LayoutParams p)
{
return
new
MarginLayoutParams(p);
}
@Override
public
ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs)
{
return
new
MarginLayoutParams(getContext(), attrs);
}
@Override
protected
ViewGroup.LayoutParams generateDefaultLayoutParams()
{
return
new
MarginLayoutParams(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);
int
width =
0
;
int
height =
0
;
/**
* 记录每一行的宽度,width不断取最大宽度
*/
int
lineWidth =
0
;
/**
* 每一行的高度,累加至height
*/
int
lineHeight =
0
;
int
cCount = getChildCount();
for
(
int
i =
0
; i < cCount; i++)
{
View child = getChildAt(i);
measureChild(child, widthMeasureSpec, heightMeasureSpec);
MarginLayoutParams lp = (MarginLayoutParams) child
.getLayoutParams();
int
childWidth = child.getMeasuredWidth() + lp.leftMargin
+ lp.rightMargin;
int
childHeight = child.getMeasuredHeight() + lp.topMargin
+ lp.bottomMargin;
/**
* 如果加入当前child,则超出最大宽度,则的到目前最大宽度给width,类加height 然后开启新行
*/
if
(lineWidth + childWidth > sizeWidth)
{
width = Math.max(lineWidth, childWidth);
lineWidth = childWidth;
height += lineHeight;
lineHeight = childHeight;
}
else
{
lineWidth += childWidth;
lineHeight = Math.max(lineHeight, childHeight);
}
if
(i == cCount -
1
)
{
width = Math.max(width, lineWidth);
height += lineHeight;
}
}
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>();
@Override
protected
void
onLayout(
boolean
changed,
int
l,
int
t,
int
r,
int
b)
{
mAllViews.clear();
mLineHeight.clear();
int
width = getWidth();
int
lineWidth =
0
;
int
lineHeight =
0
;
List<View> lineViews =
new
ArrayList<View>();
int
cCount = getChildCount();
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)
{
mLineHeight.add(lineHeight);
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++)
{
lineViews = mAllViews.get(i);
lineHeight = mLineHeight.get(i);
Log.e(TAG,
"第"
+ i +
"行 :"
+ lineViews.size() +
" , "
+ lineViews);
Log.e(TAG,
"第"
+ i +
"行, :"
+ lineHeight);
for
(
int
j =
0
; j < lineViews.size(); j++)
{
View child = lineViews.get(j);
if
(child.getVisibility() == View.GONE)
{
continue
;
}
MarginLayoutParams lp = (MarginLayoutParams) child
.getLayoutParams();
int
lc = left + lp.leftMargin;
int
tc = top + lp.topMargin;
int
rc =lc + child.getMeasuredWidth();
int
bc = tc + child.getMeasuredHeight();
Log.e(TAG, child +
" , l = "
+ lc +
" , t = "
+ t +
" , r ="
+ rc +
" , b = "
+ bc);
child.layout(lc, tc, rc, bc);
left += child.getMeasuredWidth() + lp.rightMargin
+ lp.leftMargin;
}
left =
0
;
top += lineHeight;
}
}
}