//因为我们需要支持margin,所以需要重写generateLayoutParams方法并创建MarginLayoutParams对象 @Override public LayoutParams generateLayoutParams(AttributeSet attrs){ returnnew MarginLayoutParams(getContext(),attrs); } /*@Override protected ViewGroup.LayoutParams generateLayoutParams(LayoutParams p) { return new MarginLayoutParams(p); }*/ /*@Override protected LayoutParams generateDefaultLayoutParams() { return new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT); }*/
//存储每一行的最大高度 private List<Integer> heights = new ArrayList<>();
@Override protectedvoidonMeasure(int widthMeasureSpec, int heightMeasureSpec){ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//获得测量模式和大小 int widthMode = MeasureSpec.getMode(widthMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec);
//wrap_content模式下,存储宽和高 int wrapWidth = 0; int wrapHeight = 0;
//padding的宽度 int widthUsed = getPaddingLeft() + getPaddingRight();
//存储当前行的宽度 int lineWidth = widthUsed; //存储一行的最大高度 int lineHeight = 0;
//遍历子View进行测量 for (int i = 0; i < getChildCount(); i++) { //获取子View View child = getChildAt(i);
//子View为GONE则跳过 if (child.getVisibility() == View.GONE){ continue; }
@Override protectedvoidonLayout(boolean changed, int l, int t, int r, int b){ //获取视图宽度 int width = getWidth(); //记录当前行号 int line = 0; //存储padding的宽度 int widthUsed = getPaddingLeft() + getPaddingRight(); //记录当前行的宽度 int lineWidth = widthUsed; //开始的横坐标 int left = getPaddingLeft(); //开始的纵坐标 int top = getPaddingTop();
//遍历所有的子View for (int i = 0; i < getChildCount(); i++) { //获取子View View child = getChildAt(i);
//子View为GONE则跳过 if (child.getVisibility() == View.GONE){ continue; }
//计算child的left,top,right,bottom int lc = left + layoutParams.leftMargin; int tc = top + layoutParams.topMargin; int rc = lc + child.getMeasuredWidth(); int bc = tc + child.getMeasuredHeight();
//计算child的位置 child.layout(lc,tc,rc,bc);
//left向右移动一个间距 left = layoutParams.rightMargin + rc + horizontalSpace; } }