你的位置:首页 > 操作系统

[操作系统]Android 绘制view的小知识点


【onMeasure】

直接继承view的自定义控件需要重写onMeasure方法并设置wrap_content时的自身大小,否则在布局中使用wrap_content就相当于match_parent。

 @Override  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {    int widthMode = MeasureSpec.getMode(widthMeasureSpec);    int heightMode = MeasureSpec.getMode(heightMeasureSpec);    int widthSize = MeasureSpec.getSize(widthMeasureSpec);    int heightSize = MeasureSpec.getSize(heightMeasureSpec);    int width=100;//根据需求调节默认值大小    int height=100;//根据需求调节默认值大小    if(widthMode == MeasureSpec.AT_MOST && heightMode == MeasureSpec.AT_MOST){      setMeasuredDimension(width, height);    }else if(widthMode == MeasureSpec.AT_MOST){       setMeasuredDimension(width, heightSize );    }else if(heightMode == MeasureSpec.AT_MOST){ 
        setMeasuredDimension(widthSize , height);
     }
}

 

//LinearLayout    通过measure调用onMeasure

ViewGroup是一个抽象类,有一个抽象方法onLayout;没有重写onMeasure方法,但是提供了一个measureChildren来对每一个子元素进行measure

    ViewGroup的测量过程onMeasure一般都在其子类中重写,比如在LinearLayout中的onMeasure,会先判断线性方向,然后遍历测量(对每个子元素执行

           measureChildBeforeLayout()方法,这个方法内部会调用子元素的measure()方法来测量其本身的大小)子元素,子元素测量完毕, LinearLayout会测量自己的大小

           setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, childState),heightSizeAndState);

View不是抽象类

           在Activity的各个生命周期onCreat,onResume中都可能无法获取View的准确的宽高信息,因为View的measure过程和Activity的生命周期不是同步的。

    解决办法:1.在View的onWindowFocusChanged中执行view.getMeasuredWidth()

 

【onLayout】//LinearLayout    通过layout调用onLayout

layout方法确定View本身的位置,而onLayout遍历子元素(通过setChildFrame)调用子元素的layout方法确定子元素的位置。

 

【onDraw】

通过draw方法调用下面的四个方法

1.绘制背景background.draw(canvas)。

2.绘制自己onDraw(canvas)。

3.绘制children(dispatchDraw(canvas))。

4.绘制装饰(onDrawScrollBars(canvas))。

View的绘制的传递是通过dispatchDraw来实现的,(在ViewGroup中的)dispatchDraw会遍历所有子元素的draw方法,如此draw事件就可以一层层的传递下去

 

ViewRoot对应于ViewRootImpl类,它是连接WindowManager和Deco人View(FrameLayout)的纽带。