自定义ViewGrooup
public class XCflowLayout extends ViewGroup {
//储存所有子View
List<List<View>> mAllChildViews = new ArrayList<>();
//每行的高度
List<Integer> mLineHeight=new ArrayList<>();
public XCflowLayout(Context context) {
this(context,null);
}
public XCflowLayout(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public XCflowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@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);
//如果宽高为wrap_content的情况
int width=0;
int height=0;
//记录每一行的宽高
int lineWidth=0;
int lineHeight=0;
//获取一个view的个数
int childCount = getChildCount();
//循环获得每个view的数值
for(int i=0;i<childCount;i++){
View child = getChildAt(i);
//测量子View的宽高
measureChild(child,widthMeasureSpec,heightMeasureSpec);
//得到LayoutParams
MarginLayoutParams lp = (MarginLayoutParams) getLayoutParams();
//子View 占据的宽度
int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
//子View占据的高
int childHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
//换行的时候
if(lineWidth+childWidth>sizeWidth){
//对比得到最大的宽度
width=Math.max(width,lineWidth);
//重置lineWidth
lineWidth=childWidth;
//记录行高
height+= lineHeight;
lineHeight=childHeight;
}else{
//叠加行宽
lineWidth+=childWidth;
//得到最大行高
lineHeight=Math.max(lineHeight,childHeight);
}
//处理最后一个子View
if(i==childCount-1){
width=Math.max(width,lineWidth);
height+=lineHeight;
}
}
//wrap_content
setMeasuredDimension(modeWidth==MeasureSpec.EXACTLY ? sizeWidth:width,modeheight==MeasureSpec.EXACTLY ? sizeheight:height);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
mAllChildViews.clear();
mLineHeight.clear();
//获得当前ViewGroup的宽度
int width = getWidth();
int lineWidth=0;
int lineHeight=0;
// 记录当前行的View
List<View> lineViews=new ArrayList<View>();
int childCount = getChildCount();
for(int i=0;i<childCount;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){
//记录LineHeight
mLineHeight.add(lineHeight);
//记录当前的Views
mAllChildViews.add(lineViews);
//重置行高
lineWidth=0;
lineHeight=childHeight+lp.topMargin+lp.bottomMargin;
//重置view的集合
lineViews=new ArrayList();
}
lineWidth += childWidth + lp.leftMargin + lp.rightMargin;
lineHeight = Math.max(lineHeight, childHeight + lp.topMargin + lp.bottomMargin);
lineViews.add(child);
}
//处理最后一行
mLineHeight.add(lineHeight);
mAllChildViews.add(lineViews);
//设置子View的位置
int left = 0;
int top = 0;
//获取行数
int lineCount = mAllChildViews.size();
for(int i =0;i<lineCount;i++){
//当前行的Views和高度
lineViews=mAllChildViews.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 cLeft = left + lp.leftMargin;
int cTop = top + lp.topMargin;
int cRight = cLeft + child.getMeasuredWidth();
int cBottom = cTop + child.getMeasuredHeight();
//进行子View进行布局
child.layout(cLeft, cTop, cRight, cBottom);
left += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
}
left = 0;
top += lineHeight;
}
}
/**
* 与当前ViewGroup对应的LayoutParams
*/
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
// TODO Auto-generated method stub
return new MarginLayoutParams(getContext(), attrs);
}
}
MainActivty
public class MainActivity extends AppCompatActivity {
private String mNames[] = {
"好好学习","天天向上","我要疯了",
"学不会啊,怎么办呢","感觉天书一样","神啊,救救我吧!!!!!",
"安卓就是一个坑","跳下来就是一望无际的黑暗",
"老司机开车,请系好安全套","你一万多的假包真好看","腾讯视频",
"错误的方式","天道酬勤,恒者能胜","抖音专辑","不想干了 , 我要休息!!!!!!"
};
private XCflowLayout mFlowLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initChildViews();
}
private void initChildViews(){
mFlowLayout = (XCflowLayout) findViewById(R.id.flowlayout);
ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
lp.leftMargin = 5;
lp.rightMargin = 5;
lp.topMargin = 5;
lp.bottomMargin = 5;
for(int i = 0; i < mNames.length; i ++){
TextView view = new TextView(this);
view.setText(mNames[i]);
view.setTextColor(Color.BLACK);
view.setBackgroundColor(Color.GRAY);
mFlowLayout.addView(view,lp);
}
}
}