VIEWGROUP

VIEWGROUP

ViewGroup相当于一个放置View的容器,并且我们在写布局xml的时候,会告诉容器(凡是以layout为开头的属性,都是为用于告诉容器的),我们的宽度(layout_width)、高度(layout_height)、对齐方式(layout_gravity)等;当然还有margin等;于是乎,ViewGroup的职能为:给childView计算出建议的宽和高和测量模式 ;决定childView的位置;为什么只是建议的宽和高,而不是直接确定呢,别忘了childView宽和高可以设置为wrap_content,这样只有childView才能计算出自己的宽和高。

定义一个ViewGroup

内部可以传入0到4个childView,分别依次显示在左上角,右上角,左下角,右下角。
效果图

在onMeasure中计算childView的测量值以及模式,以及设置自己的宽和高:

“`objc
/**
* 计算所有ChildView的宽度和高度 然后根据ChildView的计算结果,设置自己的宽和高
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
/**
* 获得此ViewGroup上级容器为其推荐的宽和高,以及计算模式
*/
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);

    // 计算出所有的childView的宽和高
    measureChildren(widthMeasureSpec, heightMeasureSpec);
    /**
     * 记录如果是wrap_content是设置的宽和高
     */
    int width = 0;
    int height = 0;

    int cCount = getChildCount();

    int cWidth = 0;
    int cHeight = 0;
    MarginLayoutParams cParams = null;

    // 用于计算左边两个childView的高度
    int lHeight = 0;
    // 用于计算右边两个childView的高度,最终高度取二者之间大值
    int rHeight = 0;

    // 用于计算上边两个childView的宽度
    int tWidth = 0;
    // 用于计算下面两个childiew的宽度,最终宽度取二者之间大值
    int bWidth = 0;

    /**
     * 根据childView计算的出的宽和高,以及设置的margin计算容器的宽和高,主要用于容器是warp_content时
     */
    for (int i = 0; i < cCount; i++)
    {
        View childView = getChildAt(i);
        cWidth = childView.getMeasuredWidth();
        cHeight = childView.getMeasuredHeight();
        cParams = (MarginLayoutParams) childView.getLayoutParams();

        // 上面两个childView
        if (i == 0 || i == 1)
        {
            tWidth += cWidth + cParams.leftMargin + cParams.rightMargin;
        }

        if (i == 2 || i == 3)
        {
            bWidth += cWidth + cParams.leftMargin + cParams.rightMargin;
        }

        if (i == 0 || i == 2)
        {
            lHeight += cHeight + cParams.topMargin + cParams.bottomMargin;
        }

        if (i == 1 || i == 3)
        {
            rHeight += cHeight + cParams.topMargin + cParams.bottomMargin;
        }

    }

    width = Math.max(tWidth, bWidth);
    height = Math.max(lHeight, rHeight);

    /**
     * 如果是wrap_content设置为我们计算的值
     * 否则:直接设置为父容器计算的值
     */
    setMeasuredDimension((widthMode == MeasureSpec.EXACTLY) ? sizeWidth
            : width, (heightMode == MeasureSpec.EXACTLY) ? sizeHeight
            : height);
}  ```

onLayout对其所有childView进行定位(设置childView的绘制区域)

“`objc
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b)
{
int cCount = getChildCount();
int cWidth = 0;
int cHeight = 0;
MarginLayoutParams cParams = null;
/**
* 遍历所有childView根据其宽和高,以及margin进行布局
*/
for (int i = 0; i < cCount; i++)
{
View childView = getChildAt(i);
cWidth = childView.getMeasuredWidth();
cHeight = childView.getMeasuredHeight();
cParams = (MarginLayoutParams) childView.getLayoutParams();

        int cl = 0, ct = 0, cr = 0, cb = 0;

        switch (i)
        {
        case 0:
            cl = cParams.leftMargin;
            ct = cParams.topMargin;
            break;
        case 1:
            cl = getWidth() - cWidth - cParams.leftMargin
                    - cParams.rightMargin;
            ct = cParams.topMargin;

            break;
        case 2:
            cl = cParams.leftMargin;
            ct = getHeight() - cHeight - cParams.bottomMargin;
            break;
        case 3:
            cl = getWidth() - cWidth - cParams.leftMargin
                    - cParams.rightMargin;
            ct = getHeight() - cHeight - cParams.bottomMargin;
            break;

        }
        cr = cl + cWidth;
        cb = cHeight + ct;
        childView.layout(cl, ct, cr, cb);
    }

}  ```
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值