Android View 绘制流程之二:layout布局

系列文章:
Android View 绘制流程之一:measure测量
Android View 绘制流程之二:layout布局
Android View 绘制流程之三:draw绘制
Android View 绘制流程之四:绘制流程触发机制

layout(int left,int top,int right,int bottom)方法是View测绘系统的第二步,布局过程,是在measure测量后调用,四个参数就是其在父view中的相对位置;如果是ViewGroup,还要根据自己的位置、布局属性来决定子view的相对位置,对子view进行layout过程,布局子view需要重写onLayout进行。

一.layout整体流程

先来一个整体的流程图。
在这里插入图片描述
在这里插入图片描述
首先,会调用setFrame方法设置并判断新的ltrb,返回值是ltrb是否改变了:如果有一个改变的,则要返回true,向view加入DRAWN标志,说明要重绘;计算新的宽高(right-left、bottom-top),如果宽高变化了,需要重新invalidate一下原有区域,并且调用onSizeChanged回调(View可以重写该方法进行拦截);最后更新ltrb的值。如果setFrame后发现改变了位置(返回true)或者view有LAYOUT_REQUIRED标志(需要重新布局),就调用onLayout方法,然后回调为view添加的OnLayoutChangeListener,最后取消这些标志位即可;

public void layout(int l, int t, int r, int b) {
   
    ...

    int oldL = mLeft;
    int oldT = mTop;
    int oldB = mBottom;
    int oldR = mRight;

    boolean changed = isLayoutModeOptical(mParent) ?
            setOpticalFrame(l, t, r, b) : setFrame(l, t, r, b);//更新ltrb、看是否改变位置

    if (changed || (mPrivateFlags & PFLAG_LAYOUT_REQUIRED) == PFLAG_LAYOUT_REQUIRED) {
   //位置改变了或者需要重新布局
        onLayout(changed, l, t, r, b);//交由ViewGroup子类重写实现布局子view
        mPrivateFlags &= ~PFLAG_LAYOUT_REQUIRED;//取消标志位
		//调用listener
        ListenerInfo li = mListenerInfo;
        if (li != null && li.mOnLayoutChangeListeners != null) {
   
            ArrayList<OnLayoutChangeListener> listenersCopy =
                    (ArrayList<OnLayoutChangeListener>)li.mOnLayoutChangeListeners.clone();
            int numListeners = listenersCopy.size();
            for (int i = 0; i < numListeners; ++i) {
   
                listenersCopy.get(i).onLayoutChange(this, l, t, r, b, oldL, oldT, oldR, oldB);
            }
        }
    }
	//取消标志位
    mPrivateFlags &= ~PFLAG_FORCE_LAYOUT;
    mPrivateFlags3 |= PFLAG3_IS_LAID_OUT;
}
 
protected boolean setFrame(int left, int top, int right, int bottom) {
   
    boolean changed = false;
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值