流布局Flowlayout
public class
FlowLayout
extends
ViewGroup
{
public FlowLayout(Context context, AttributeSet attrs, int defStyle)
{
super (context, attrs, defStyle);
//
}
public FlowLayout(Context context, AttributeSet attrs)
{
this (context, attrs, 0 );
}
public FlowLayout(Context context)
{
this (context, null );
}
@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 ;
int height = 0 ;
int lineWidth = 0 ;
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 ;
if (lineWidth + childWidth > sizeWidth - getPaddingLeft() - getPaddingRight())
{
width = Math.max(width, lineWidth);
lineWidth = childWidth;
height += lineHeight;
lineHeight = childHeight;
} else
{
lineWidth += childWidth;
lineHeight = Math.max(lineHeight, childHeight);
}
if (i == cCount - 1 )
{
width = Math.max(lineWidth, width);
height += lineHeight;
}
}
setMeasuredDimension(
//
modeWidth == MeasureSpec. EXACTLY ? sizeWidth : width + getPaddingLeft() + getPaddingRight(),
modeHeight == MeasureSpec. EXACTLY ? sizeHeight : height + getPaddingTop()+ getPaddingBottom() //
);
}
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 + lineWidth + lp. leftMargin + lp. rightMargin > width - getPaddingLeft() - getPaddingRight())
{
mLineHeight .add(lineHeight);
mAllViews .add(lineViews);
lineWidth = 0 ;
lineHeight = childHeight + lp. topMargin + lp. bottomMargin ;
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 = getPaddingLeft();
int top = getPaddingTop();
int lineNum = mAllViews .size();
for ( int i = 0 ; i < lineNum; i++)
{
lineViews = mAllViews .get(i);
lineHeight = mLineHeight .get(i);
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();
child.layout(lc, tc, rc, bc);
left += child.getMeasuredWidth() + lp. leftMargin
+ lp. rightMargin ;
}
left = getPaddingLeft() ;
top += lineHeight ;
}
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs)
{
return new MarginLayoutParams(getContext(), attrs);
}
}
random = new Random();
for ( final String str : source ) {
TextView tv= new TextView( this );
tv.setText(str);
ViewGroup.MarginLayoutParams params= new ViewGroup.MarginLayoutParams(ViewGroup.LayoutParams. WRAP_CONTENT ,
ViewGroup.LayoutParams. WRAP_CONTENT );
params. leftMargin = DensityUtils.dip2px( this , 0 );
params. rightMargin = DensityUtils.dip2px( this , 10 );
params. bottomMargin = DensityUtils.dip2px( this , 10 );
params. topMargin = DensityUtils.dip2px( this , 10 );
tv.setLayoutParams(params);
tv.setTextColor(Color. GRAY );
tv.setBackgroundResource(R.drawable. item_have_history_rv_hot_bg );
tv.setClickable( true );
tv.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
TextView tvx= (TextView) v;
String s= spUtil .getSearchHistory();
s=s+tvx.getText().toString().trim()+ "," ;
spUtil .saveSearchHistory(s);
}
});
int padding=DensityUtils.dip2px( this , 3 );
tv.setPadding(padding,padding,padding,padding);
flowlayout .addView(tv);
}
}
{
public FlowLayout(Context context, AttributeSet attrs, int defStyle)
{
super (context, attrs, defStyle);
//
}
public FlowLayout(Context context, AttributeSet attrs)
{
this (context, attrs, 0 );
}
public FlowLayout(Context context)
{
this (context, null );
}
@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 ;
int height = 0 ;
int lineWidth = 0 ;
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 ;
if (lineWidth + childWidth > sizeWidth - getPaddingLeft() - getPaddingRight())
{
width = Math.max(width, lineWidth);
lineWidth = childWidth;
height += lineHeight;
lineHeight = childHeight;
} else
{
lineWidth += childWidth;
lineHeight = Math.max(lineHeight, childHeight);
}
if (i == cCount - 1 )
{
width = Math.max(lineWidth, width);
height += lineHeight;
}
}
setMeasuredDimension(
//
modeWidth == MeasureSpec. EXACTLY ? sizeWidth : width + getPaddingLeft() + getPaddingRight(),
modeHeight == MeasureSpec. EXACTLY ? sizeHeight : height + getPaddingTop()+ getPaddingBottom() //
);
}
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 + lineWidth + lp. leftMargin + lp. rightMargin > width - getPaddingLeft() - getPaddingRight())
{
mLineHeight .add(lineHeight);
mAllViews .add(lineViews);
lineWidth = 0 ;
lineHeight = childHeight + lp. topMargin + lp. bottomMargin ;
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 = getPaddingLeft();
int top = getPaddingTop();
int lineNum = mAllViews .size();
for ( int i = 0 ; i < lineNum; i++)
{
lineViews = mAllViews .get(i);
lineHeight = mLineHeight .get(i);
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();
child.layout(lc, tc, rc, bc);
left += child.getMeasuredWidth() + lp. leftMargin
+ lp. rightMargin ;
}
left = getPaddingLeft() ;
top += lineHeight ;
}
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs)
{
return new MarginLayoutParams(getContext(), attrs);
}
}
流布局应用实例
private void showFlowlayout() {random = new Random();
for ( final String str : source ) {
TextView tv= new TextView( this );
tv.setText(str);
ViewGroup.MarginLayoutParams params= new ViewGroup.MarginLayoutParams(ViewGroup.LayoutParams. WRAP_CONTENT ,
ViewGroup.LayoutParams. WRAP_CONTENT );
params. leftMargin = DensityUtils.dip2px( this , 0 );
params. rightMargin = DensityUtils.dip2px( this , 10 );
params. bottomMargin = DensityUtils.dip2px( this , 10 );
params. topMargin = DensityUtils.dip2px( this , 10 );
tv.setLayoutParams(params);
tv.setTextColor(Color. GRAY );
tv.setBackgroundResource(R.drawable. item_have_history_rv_hot_bg );
tv.setClickable( true );
tv.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
TextView tvx= (TextView) v;
String s= spUtil .getSearchHistory();
s=s+tvx.getText().toString().trim()+ "," ;
spUtil .saveSearchHistory(s);
}
});
int padding=DensityUtils.dip2px( this , 3 );
tv.setPadding(padding,padding,padding,padding);
flowlayout .addView(tv);
}
}