android view绘制原理

  本文详细介绍view的绘制过程,view的绘制过程由measure、layout、draw 三部分组成。

measure : 测量view的宽和高。
layout : 确定view 四个点(top、left、 right、bottom)在父容器的最终位置。
draw : 将view绘制到屏幕上面。
view的绘制首先调用ViewRootImpl类的performTraversales方法,里面决定要不要measure、layout、draw 。具体过程如下:
这里写图片描述

会先遍历ViewGroup的子View,其实最后就是调用View的Measure、Layout、Draw三个方法。

1:measure
测量过程主要与MeasureSpec和LayoutParams有关系,MeasureSpec是一个32位int型数,高2位代表SpecMode ,低30位 表示 SpecSize。
SpecMode有3种:UNSPECIFIED、EXACTLY、AT_MOST。
UNSPECIFIED:父容器不对View做任何的限制,要多大给多大。
EXACTLY:父容器已经检测出View所需的大小,其值就是SpecSize。
AT_MOST:父容器指定了一个可用大小,View不能超过这个值。
LayoutParams有3个:FILL_PARENT、WRAP_CONTENT 、MATCH_PARENT。
子View的MeasureSpec的值由父容器的MeasureSpec和子View的 LayoutParams决定。
具体来说:如果子View的LayoutParams为MATCH_PARENT,父容器的SpecMode为AT_MOST,那么子View也是AT_MOST,且其大小不会超过父容器的剩余空间。

2:layout

public void layout(int l, int t, int r, int b) {
        if ((mPrivateFlags3 & PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT) != 0) {
            onMeasure(mOldWidthMeasureSpec, mOldHeightMeasureSpec);
            mPrivateFlags3 &= ~PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;
        }

        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);

        if (changed || (mPrivateFlags & PFLAG_LAYOUT_REQUIRED) == PFLAG_LAYOUT_REQUIRED) {
            onLayout(changed, l, t, r, b);
            mPrivateFlags &= ~PFLAG_LAYOUT_REQUIRED;

            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;
    }

在view的layout函数中,首先会通过setFrame获取到 mLeft、mTop、mBottom、mRight4个点的值,然后调用onLayout函数。

protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    }

可以看出,在View的onLayout函数中并没有具体的方法实现,onLayout跟具体的布局有关系,具体可以看LinearLayout的函数实现。

3:draw
Draw函数主要是将View绘制到屏幕上,可以从源码上面看出主要包含以下几步,这里就不贴源码了:
1:绘制背景
2:绘制自己
3:绘制children
4:绘制装饰

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值