Android View绘制流程_Android 绘制View的小知识点
2017-11-22 14:31:24  By: dwtedx

【onMeasure】

直接继承view或ViewGroup的自定义控件需要重写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)的纽带。

 

自定义View须知:

1.让View支持wrap_content;

2.如果必要,让你的View支持padding:这是因为直接继承View的控件,如果不在draw方法中处理paddong,那么padding属性是无法起作用的。另外继承自ViewGroup的控件需要在onMeasure和onLayout中考虑padding和子元素的margin对其造成的影响,不然将导致padding和子元素的margin失效。

3.尽量不要在View中使用handler,没必要,因为View中本身就有post系列的方法,可以替代handler

4.View中如果有线程或动画,需要及时停止,参考View#onDetachedFromWindow。


若资源对你有帮助、浏览后有很大收获、不妨小额打赏我一下、你的鼓励是维持我不断写博客最大动力

想获取DD博客最新代码、你可以扫描下方的二维码、关注DD博客微信公众号(ddblogs)

或者你也可以关注我的新浪微博、了解DD博客的最新动态:DD博客官方微博(dwtedx的微博)

如对资源有任何疑问或觉得仍然有很大的改善空间、可以对该博文进行评论、希望不吝赐教

为保证及时回复、可以使用博客留言板给我留言: DD博客留言板(dwtedx的留言板)

感谢你的访问、祝你生活愉快、工作顺心、欢迎常来逛逛


快速评论


技术评论

  • 该技术还没有评论、赶快抢沙发吧...
DD记账
top
+