zoukankan      html  css  js  c++  java
  • Android 绘制view的小知识点

    【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。

  • 相关阅读:
    认识hasLayout——IE浏览器css bug的一大罪恶根源 转
    web网站p教程 转
    可遇不可求的Question之SQLServer的INSERT ON DUPLICATE KEY UPDATE语法篇
    可遇不可求的Question之Protoc.exe无法编译proto文件篇
    python各个版本的下载地址
    可遇不可求的Question之WCF发布无法运行篇
    [转]理解JSON:3分钟课程
    可遇不可求的Question之Silverlight发布IIS设置篇
    可遇不可求的Question之C#中的匿名事件导致内存泄露的解决篇
    可遇不可求的Question之mysql连接数暴增的解决方法篇
  • 原文地址:https://www.cnblogs.com/lipeineng/p/5773967.html
Copyright © 2011-2022 走看看