4.关于View的绘制 (中):layout

1.Layout过程

1.1 View的layout

view的layout方法用来确定view本身的位置

public void layout(int l, int t, int r, int b) {
	...
	// 1.
	setFrame(l,t,r,b)
	// 2.
	onLayout(changed,l,t,r,b)
}
  1. 先通过setFrame来设定4个顶点位置,view在父容器中位置就确定下来,4个参数是基于父容器的左、上、右、下距离
    protected boolean setFrame(int left, int top, int right, int bottom) {
        boolean changed = false;
		...
    }
  1. 在layout内部调用onLayout, 用于父容器确定子元素位置(View#onLayout() 默认是空实现),如果特殊需求一般不需要覆写
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    }

1.2 ViewGroup的layout

确定所有子元素的位置
viewGroup的layout为final方法,不能覆写,其实现为View.layout

    @Override
    public final void layout(int l, int t, int r, int b) {
        if (!mSuppressLayout && (mTransition == null || !mTransition.isChangingLayout())) {
            if (mTransition != null) {
                mTransition.layoutChange(this);
            }
            super.layout(l, t, r, b);
        } else {
            // record the fact that we noop'd it; request layout when transition finishes
            mLayoutCalledWhileSuppressed = true;
        }
    }
  1. ViewGroup.onLayout() 为抽象方法,需要覆写
    @Override
    protected abstract void onLayout(boolean changed,
            int l, int t, int r, int b);

比如自定义FlowLayout,继承自ViewGroup,如下覆写onLayout(…)

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        for (int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);
            Rect rect = (Rect) getChildAt(i).getTag();
            child.layout(rect.left, rect.top, rect.right, rect.bottom);
        }
    }

2. 总结

  1. View与ViewGroup的layout实为一套流程,View#onLayout()默认是空实现,ViewGroup#onLayout()是抽象方法,需要用户自己实现,需要根据具体的布局来实现,可参考TextView, LinearLayout的实现。
  2. measure过程确定测量宽高,layout过程确定4定点位置即最终宽高,有何不同?
    measure, getMeasureWidth
    layout, getWidth = mRight - mLeft
    二者时序不同,值是相等的, measure先,layout后;
    若覆写View.layout ,修改4点的参数,则会导致二者不同
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值