原文链接:https://blog.csdn.net/ldld1717/article/details/80458917

1. 简单实现水平排列效果

我们先自定义一个ViewGroup作为布局容器,实现一个从左往右水平排列(排满换行)的效果:

/**
 * 自定义布局管理器的示例。
 */
public class CustomLayout extends ViewGroup {
      private static final String TAG = "CustomLayout";

    public CustomLayout(Context context) {
        super(context);
    }

    public CustomLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CustomLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    /**
     * 要求所有的孩子测量自己的大小,然后根据这些孩子的大小完成自己的尺寸测量
     */
    @SuppressLint("NewApi") @Override
    protected void onMeasure( int widthMeasureSpec, int heightMeasureSpec) {
        // 计算出所有的childView的宽和高 
        measureChildren(widthMeasureSpec, heightMeasureSpec); 
        //测量并保存layout的宽高(使用getDefaultSize时,wrap_content和match_perent都是填充屏幕)
        //稍后会重新写这个方法,能达到wrap_content的效果
        setMeasuredDimension( getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
                getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
    }

    /**
     * 为所有的子控件摆放位置.
     */
    @Override
    protected void onLayout( boolean changed, int left, int top, int right, int bottom) {
        final int count = getChildCount();
        int childMeasureWidth = 0;
        int childMeasureHeight = 0;
        int layoutWidth = 0;    // 容器已经占据的宽度
        int layoutHeight = 0;   // 容器已经占据的宽度
        int maxChildHeight = 0; //一行中子控件最高的高度,用于决定下一行高度应该在目前基础上累加多少
        for(int i = 0; imaxChildHeight){
                  maxChildHeight = childMeasureHeight;
            }

             //确定子控件的位置,四个参数分别代表(左上右下)点的坐标值
            child.layout(left, top, right, bottom);
        }
    }
}

布局文件:




    

运行效果:

Android自定义ViewGroup(简单实现水平排列效果)_第1张图片
运行成功,是不是略有成就感?这个布局就是简单版的LinearLayout设置android:orientation ="horizontal"的效果,比他还牛X一点,还能自动换行(哈哈)。接下来我们要实现一个功能,只需要在布局文件中指定布局属性,就能控制子控件在什么位置(类似相对布局RelativeLayout)。

点击下方链接免费获取Android进阶资料:

https://shimo.im/docs/tXXKHgdjPYj6WT8d/