传承者(Inheritors)打造共同进步生态圈!!!
转载:http://blog.csdn.net/lmj623565791/article/details/38352503
考虑宽高,设置宽高是重点
flag_04
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<solid android:color="#7690A5" >
</solid>
<corners android:radius="5dp"/>
<padding
android:bottom="2dp"
android:left="10dp"
android:right="10dp"
android:top="2dp" />
</shape>
main
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.administrator.testapplication.Main2Activity">
<com.example.administrator.testapplication.FlowLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<TextView
style="@style/text_flag_01"
android:background="@drawable/flag_04"
android:text="Welcome"
android:textColor="#323232" />
<TextView
style="@style/text_flag_01"
android:background="@drawable/flag_04"
android:text="IT工程师"
android:textColor="#323232" />
<TextView
style="@style/text_flag_01"
android:background="@drawable/flag_04"
android:text="学习ing"
android:textColor="#323232" />
<TextView
style="@style/text_flag_01"
android:background="@drawable/flag_04"
android:text="恋爱ing"
android:textColor="#323232" />
<TextView
style="@style/text_flag_01"
android:background="@drawable/flag_04"
android:text="挣钱ing"
android:textColor="#323232" />
<TextView
style="@style/text_flag_01"
android:background="@drawable/flag_04"
android:text="努力ing"
android:textColor="#323232" />
<TextView
style="@style/text_flag_01"
android:background="@drawable/flag_04"
android:text="I thick i can"
android:textColor="#323232" />
<TextView
style="@style/text_flag_01"
android:background="@drawable/flag_04"
android:text="dddddd"
android:textColor="#323232" />
<TextView
style="@style/text_flag_01"
android:background="@drawable/flag_04"
android:text="黑恶黑诶诶"
android:textColor="#323232" />
<TextView
style="@style/text_flag_01"
android:background="@drawable/flag_04"
android:text="I thick i can"
android:textColor="#323232" />
</com.example.administrator.testapplication.FlowLayout>
</LinearLayout>
style
<style name="text_flag_01">
<item name="android:layout_width" >wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_margin">4dp</item>
<item name="android:background">@drawable/flag_01</item>
<item name="android:textColor">#ffffff</item>
</style>
FlowLayout
public class FlowLayout extends ViewGroup{
public FlowLayout(Context context) {
super(context);
}
public FlowLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public FlowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new MarginLayoutParams(getContext(),attrs);
}
/**
* 获得设置子控件的测量模式,大小,根据所有子控件设置自己的宽和高
* @param widthMeasureSpec
* @param heightMeasureSpec
*/
@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);
//如果wrap_content情况下,记录宽和高
int width =0, height = 0;
//记录每一行的宽度,width不断取最大的宽度
int lineWidth = 0;
//每一行的高度,累计至height
int lineHeight = 0;
int cCount = getChildCount();
//遍历每个子元素
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;
//如果加入当前child,则超出最大宽度,则给目前最大宽度,启动新的一行
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;
}
}
setMeasuredDimension((modeWidth == MeasureSpec.EXACTLY )? sizeWidth:width,(modeHeight == MeasureSpec.EXACTLY )? sizeHeight:height);
}
/**
* 存储所有的view
* 按行记录
*
*/
private List<List<View>> mAllViews = new ArrayList<>();
//记录每一行的最大高度
private List<Integer> mLineHeight = new ArrayList<>();
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
mAllViews.clear();
mLineHeight.clear();
int width = getWidth();
int lineWidth = 0,lineHeight = 0;
// 存储每一行所有的childView
List<View> lineViews = new ArrayList<>();
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){
//记录这一行所有的View 以及最大的高度
mLineHeight.add(lineHeight);
//将当前的childView保存,然互开启新的ArrayList保存下一行的childView
mAllViews.add(lineViews);
lineWidth = 0;//重置行宽
lineViews = new ArrayList<>();
}
//如果不需要换行,则累加
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, 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.rightMargin + lp.leftMargin;
}
left = 0;
top += lineHeight;
}
}
}