第三章 控件架构与自定义控件详解

3.1 控件架构

  • 通过ViewGroup整个控件组成一个控件树。

Activity->PhoneWindow->DecorView->Title和ContentView(contentView本质上为一个Framelayout)

  • DecorView将要显示的内容呈现在了PhoneWindow上。

所有View的监听事件都是通过WindowManagerService来进行接收。
当程序在onCreate()中调用setContentView()之后ActivityManagerService会回调onResume()方法,此时系统才会把整个DecorView添加到PhoneWindow中,并显示出来,从而最终完成界面的绘制。所以requestWindowFeature(Window.Feature_NO_TITLE)要在setContentView之前调用。

3.2 View的测量

说到测量首先得说下MeasuerSpec的作用:

1 MeasureSpec封装了父布局传递给子View的布局要求。
2 MeasureSpec可以表示宽和高
3 MeasureSpec由size和mode组成

测量模式分为三种:
  • EXACTLY : width或height为具体值时,或者为match_parent时。

  • AT_MOST:width或height为wrap_content时。

  • UNSPECIFIED:不指定,View想多大就多大,自定义View时才有机会使用。

注意:View类默认的onMeasure()方法只支持EXACTLY模式,所以在自定义控件的时候必须重写onMeasure()方法指定wrap_content时的大小,才能使View支持wrap_content属性。

  • onMeasure()最终调用setMeasuredDimension(measureWidth(widthMeasureSpec), measureWidth(heightMeasureSpec))方法。
measureWidth()方法的基本模板:
private int measureWidth(int measureSpec){
    int result =0;
    int specMode = MeasureSpec.getMode(measureSpec);
    int specSize = MeasureSpec.getSize(measureSpec);
    if(specMode == MeasureSpec.EXACTLY){
        result = specSize;
    }else{
        result =200;//需要具体测量,这里给定具体值
        if(specMode == MeasureSpec.AT_MOST){
        result = Math.min(result, specSize);//取最小值
       }
    }
    return result;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容