《Android开发艺术探索》读书笔记 (4) 第4章 View的工作原理

来源:互联网 发布:唯一网络上市 编辑:程序博客网 时间:2024/04/28 13:38

自定义View

  1. View常见的回调方式:
    构造方法:(比较常见,经常通过构造方法完成初始化对象等操作);
    onVisibilityChanged: 自定义view里面提供了一个状态模式的实现,允许在View 的visibility 发生改变时,引发执行onVisibilityChanged 方法中的动作。
    onAttach(Activity):当Fragment与Activity发生关联时调用

  2. 实现方式:

    (1).继承View,重写onDraw方法.具体过程:measure-draw.
    需注意:在onMeasure()里面,对wrap_content的支持,主要是MeasureSpec.AT_MOST和MeasureSpec.EXACTLY这两个情况的判定赋值,在onDraw()里面,对padding的支持,主要是getpaddingleft\bottom\top\right等判断;

    (2).继承ViewGroup派生特殊的Layout,具体过程:measure-layout,相关滑动\事件拦截的综合应用.
    需注意:measure过程,除了完成自己的measure以外,还需要去遍历调用所有子元素的measure方法–取出子元素的layoutparams来创建MeasureSpec.再进行高度和宽度的叠加.

    (3),继承特点的View,例如:textView,EidtText等,可参考Android 带清除功能的输入框控件ClearEditText,仿IOS的输入框 http://blog.csdn.net/xiaanming/article/details/11066685看源码.

    (4)继承特定的ViewGroup,例如:LinearLayout\RelativeLayout.可参考自定义RelativeLayout实现Topbarhttp://download.csdn.net/detail/qq_28690547/9398303看源码.

    常见注意事项:
    (1).支持wrap_content,如上所述,onmeasure里面
    (2).支持padding,如上所述,ondraw里面
    (3).不要在View里面使用handler,直接用post
    (4).在onAttachedToWindow()开始动画或启动线程;在onDetachedFromWindow()里面,停止动画和线程,经常使用
    (5).View带滑动嵌套情形,需要处理好滑动冲突.

  3. 绘制流程
    (1).onMeasure(int widthMeasureSpec, int heightMeasureSpec),测量View的宽和高;标准代码:见书P186,P187
    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);        int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);        int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);        if (widthSpecMode == MeasureSpec.AT_MOST                && heightSpecMode == MeasureSpec.AT_MOST) {            setMeasuredDimension(mWidth, mHeight);//mWidth,mHeight指定默认的内部高宽        } else if (widthSpecMode == MeasureSpec.AT_MOST) {            setMeasuredDimension(mWidth, heightSpecSize);        } else if (heightSpecMode == MeasureSpec.AT_MOST) {            setMeasuredDimension(widthSpecSize, mHeight);        }    }

(2). onLayout(boolean changed, int left, int top, int right,int bottom),主要是调用子元素的view.layout(l, t, r, b)这个方法,去固定位置

(3). draw(Canvas canvas),主要是通过Paint将View绘制到屏幕上面.绘制过程:
①.绘制背景background.draw(canvas);
②.绘制自己onDraw();
③.绘制children(dispatchDraw);
④.绘制装饰(onDrawScrollBars);

  1. SepcMode的含义:

    UNPSECIFIED:父容器不对View有任何限制,要多大给多大,这种情况一般用于系统内部,表示一种测量状态,一般不考虑

    EXACTLY:表示父容器检测出View所需要的精确大小,View的大小就是SpecSize所指定的值,一般对应match_parent和具体的数字
    AT_MOST:表示View的大小不能超过这个父容器指定的值,一般应用于wrap_content;

  2. 在Activity中去获取View的高度:
    (1).Activity的onWindowFocusChanged(boolean hasFocus)中,通过getMeasureWidth()来获取View的高宽
    (2).Activity的onStart()中,通过view.post去通过getMeasureWidth()来获取View的高宽
    (3).这种方式也是我用的比较多的,使用OnGlobalLayoutListener接口,通过getViewTreeObserver同样通过getMeasureWidth()来获取View的高宽;

同章大牛笔记

http://hujiaweibujidao.github.io/blog/2015/12/01/Art-of-Android-Development-Reading-Notes-4/

0 0
原创粉丝点击