自定义流式布局

来源:互联网 发布:vb6.0软件下载 编辑:程序博客网 时间:2024/04/19 11:23

//自定义VIewGroup需要重写以下的方法

1,onmeasure::测量子VIew的宽和高 ,设置自己的宽和高 

2,onlayout :设置子View的位置

onmeasure:根据子View的布局文件,为子View设置测量模式和测量值。

测量=测量模式+测量值;

测量模式:3种:
1,EXACTLY(精确的): 100dp,match_parent

2. AT_MOST(至多): wrapcontent

3, UNSPCIFIED (无限制):子控件想要多大就给多大 (很少用到)

关于VIewGroup--LayoutParams

子VIew.getLayoutParams();//获取到的是子View的父控件的layoutparams



package com.example.viewGroup;


import java.util.ArrayList;
import java.util.List;


import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;


public class MyviewGroup extends ViewGroup {


public MyviewGroup(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}


// 设置子View的getLayoutParams()方法获取到的信息
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
// TODO Auto-generated method stu
return new MarginLayoutParams(getContext(), attrs);
}


// 测量VIewGroup和子VIew 的宽度和高度
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
int ModeWidth = MeasureSpec.getMode(widthMeasureSpec);
int sizeHeigth = MeasureSpec.getSize(heightMeasureSpec);
int ModeHeight = MeasureSpec.getMode(heightMeasureSpec);


// 当设置为Wrap_content时候计算的宽和高度
int width = 0;
int height = 0;


int cCount = getChildCount();// 获取孩子的个数
int LineWidth = 0;
int LineHeight = 0;
for (int i = 0; i < cCount; i++) {
View child = getChildAt(i);
measureChild(child, widthMeasureSpec, heightMeasureSpec);
MarginLayoutParams p = (MarginLayoutParams) child.getLayoutParams();
int childWidth = child.getMeasuredWidth() + p.leftMargin
+ p.rightMargin;
int childHeigth = child.getMeasuredHeight() + p.topMargin
+ p.bottomMargin;


if (LineWidth + childWidth > sizeWidth) {// 换行
height += LineHeight;
LineHeight = childHeigth;
width = Math.max(LineWidth, width);
LineWidth = childWidth;
} else {// 不换行
LineWidth += childWidth;
LineHeight = Math.max(LineHeight, childHeigth);
}


}
// 处理最后一行
width = Math.max(LineWidth, width);
height += LineHeight;
System.out.println("sizeWidth==" + sizeWidth);
System.out.println("sizeHeigth==" + sizeHeigth);


setMeasuredDimension(ModeWidth == MeasureSpec.EXACTLY ? sizeWidth
: width, ModeHeight == MeasureSpec.EXACTLY ? sizeHeigth
: height);
}


private List<List<View>> AllViews = new ArrayList<List<View>>();
private List<Integer> lineHeights = new ArrayList<Integer>();


// 设置子View的位置
@Override
protected void onLayout(boolean arg0, int arg1, int arg2, int arg3, int arg4) {
// TODO Auto-generated method stub
AllViews.clear();
lineHeights.clear();// 会多次调用
lineHeights = new ArrayList<Integer>();
int width = getWidth();
int cCount = getChildCount();
int lineWidth = 0;
int lineHeight = 0;
List<View> lineViews = new ArrayList<View>();
for (int i = 0; i < cCount; i++) {
View child = getChildAt(i);
MarginLayoutParams p = (MarginLayoutParams) child.getLayoutParams();
int childWidth = child.getMeasuredWidth() + p.leftMargin
+ p.rightMargin;
int childHeigth = child.getMeasuredHeight() + p.topMargin
+ p.bottomMargin;
if (lineWidth + childWidth > width) {// 要换行
AllViews.add(lineViews);
lineHeights.add(lineHeight);
lineWidth = 0;
lineHeight = childHeigth;
lineViews = new ArrayList<View>();
System.out.println("换行了");
}
lineViews.add(child);
lineWidth += childWidth;
lineHeight = Math.max(lineHeight, childHeigth);


}
// 处理最后的一行
AllViews.add(lineViews);
lineHeights.add(lineHeight);


int top = 0;
int left = 0;
for (int i = 0; i < AllViews.size(); i++) {
lineViews = AllViews.get(i);
int current_width = 0;
int currentHeigth = lineHeights.get(i);


for (int j = 0; j < lineViews.size(); j++) {
View view = lineViews.get(j);
MarginLayoutParams p = (MarginLayoutParams) view
.getLayoutParams();
int shang = top;
int xia = top + currentHeigth;
int zuo = left + p.leftMargin;
int you = left + p.leftMargin + view.getMeasuredWidth();
left += p.leftMargin + view.getMeasuredWidth() + p.rightMargin;
view.layout(zuo, shang, you, xia);
}
left = 0;
top += currentHeigth;
}
}


}

0 0
原创粉丝点击