美文网首页Android面试
(十一)View绘制机制面试问题

(十一)View绘制机制面试问题

作者: lkmc2 | 来源:发表于2017-07-31 13:32 被阅读75次

一、View树的绘制流程

measure-->layout-->draw

measure:是否重新计算视图大小。

layout:是否需要重新安置视图位置。

draw:是否需要重绘。

二、measure

measure 和 layout流程

1.ViewGroup.LayoutParams :用来指定视图高度和宽度的参数,不包括Padding。

2.MeasureSpec :表示测量规格。32位的Int值,高二位表示模式,后三十位表示测量规格的大小。

(1)UNSPECIFIED:不限定子视图尺寸大小。

(2)EXACTLY:父容器会为子视图确定一个尺寸大小,无论子视图要求多大,都要在父容器的限制内。

(2)AT_MOST:父容器会为子视图指定一个最大的尺寸,子视图所有的大小都必须在这个尺寸范围内。对应wrap_content。此时父容器无法获取子视图的大小,只能子视图自己根据需求设定。

ViewGroup.LayoutParams最终会被封装成MeasureSpec。

measure——重要方法

measure会从父容器遍历子View的measure方法,会根据ViewGroup.MeasureSpec和子View的LayoutParams来决定子视图的测量规格,通过这个测量规格进一步获取到子View的宽高,一层一层向下传递,不断保存整个父容器的测量宽高。

1.measure:该方法会调用onMeasure方法。

2.onMeasure:该方法会调用setMeasuredDimension()方法。

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
                getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
}

3.setMeasuredDimension():该方法完成整个的测量过程。

protected final void setMeasuredDimension(int measuredWidth, int measuredHeight) {
        boolean optical = isLayoutModeOptical(this);
        if (optical != isLayoutModeOptical(mParent)) {
            Insets insets = getOpticalInsets();
            int opticalWidth  = insets.left + insets.right;
            int opticalHeight = insets.top  + insets.bottom;

            measuredWidth  += optical ? opticalWidth  : -opticalWidth;
            measuredHeight += optical ? opticalHeight : -opticalHeight;
        }
        setMeasuredDimensionRaw(measuredWidth, measuredHeight);
}

三、layout

onLayout方法是用来设置与父容器的摆放关系的,自定义View需重写该方法。

View中的onLayout是个空方法。

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

LinearLaout中的onLayout如下:

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    if (mOrientation == VERTICAL) {
        layoutVertical(l, t, r, b);
    } else {
        layoutHorizontal(l, t, r, b);
    }
}

四、draw

两个容易混淆的方法:

1.invalidate():请求系统重绘,未发生变化时不会调用。

2.requestLayout():当布局(方向、尺寸等)发生变化时,需手动调用,该方法会触发measure和layout的过程,而不会调用draw方法。

相关文章

  • (十一)View绘制机制面试问题

    一、View树的绘制流程 measure-->layout-->draw measure:是否重新计算视图大小。 ...

  • View绘制及事件机制原理

    一、View绘制流程机制 1、View绘制起点 performTraversals()方法触发了View 的绘制。...

  • Android大厂面试题锦集(BAT TMD JD 小米)

    1.android事件分发机制,请详细说下整个流程 事件分发(面试).png 2.android view绘制机制...

  • 4.1View相关-View绘制详解

    View的绘制机制 view树的绘制流程 measure方法 layout方法 draw方法 1.view树的绘制...

  • 第十二章 View绘制流程

    一、Android View树结构 二、View绘制机制 1.View绘制的流程:measure(测量)->lay...

  • Android自定义控件系列博客

    绘制机制 先好好的理解一下绘制流程 公共技术点之 View 绘制流程 GcsSloop---自定义View系列自定...

  • View 绘制机制

    1. View 树的绘图流程 当 Activity 接收到焦点的时候,它会被请求绘制布局,该请求由 Android...

  • View绘制机制

    心是被委屈撑大的,优秀是用痛苦磨成的。— 《等一个人读书》 写在前面 作为Android开发人员,在应用开发过程中...

  • Android View

    1. View绘制机制 1.1 View树的绘制流程 判断是否需要重新计算视图大小(measure) 是否重新需要...

  • Android高级进阶指南

    android 触摸事件传递机制 android view的绘制流程 android 的动画机制 Support ...

网友评论

    本文标题:(十一)View绘制机制面试问题

    本文链接:https://www.haomeiwen.com/subject/dutrlxtx.html