首页 > 代码库 > Android读书笔记3:控件架构以及自定义控件
Android读书笔记3:控件架构以及自定义控件
安卓平台上这么多多姿多彩的控件是怎么制作出来的?有系统自定义的,也有开发者在系统的基础上进行自定义的。但是他们一定都遵循一定的规则,那就是android对于控件的架构设计。
言简意赅地说下:
1、所有的控件都有 共同的父类,要么父类是View,要么父类是ViewGroup,顾名思义,后者意思是View的群组,前者是单个控件。
有一个概念叫做控件树,即 所有的控件如果画成结构图,一定是一个树状结构图,我们activity里面用的findViewById就是按照树的深度优先遍历来查找对应的view( 从这里看来,如果xml里面写过太过复杂,有可能影响findViewById的效率)。
View一定是要在ViewGroup内部的,ViewGroup对于其内部的View进行统一调度和分配,控制整个视图效果。
如图:这是AndroidStudio里面的一个组件树,表示一个layout.xml里面所有组件的结构图。
2、对于Activity的代码应该都不陌生,在onCreate方法内部,调用了setContentView之后,activity的内容就会被绘制出来。而绘制的第一步,就是测量Measure。每一个组件在创建之后,都会被分配一个矩形区域,作为它的所属区域用于绘制视图。那这个矩形区域多大,位置在哪
矩形的大小,是由View内部的一个方法:onMeasure()
这是View:onMeasure的一段注释。大概意思是:
如果这个方法被子类重写了,那么子类就有责任确保测量过的宽高至少是view的最小宽高,具体怎么理解,请看下面的代码。
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { Log.d("MyTag", "onMeasure"); setMeasuredDimension(myMeasure(widthMeasureSpec, 400), myMeasure(heightMeasureSpec, 100)); } /** * 如果写自定义组件,那么这段代码基本可以作为 measure 的模板 * * @param measureSpec * @param defaultValue * @return */ private int myMeasure(int measureSpec, int defaultValue) { int result = 0; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); // 精确模式. // 如果在xml内部,定义组件的宽/高的时候,使用的是具体的数字+单位,这种组合。 // 那么就是精确模式,因为在xml里面明确指定了组件的宽/高。 if (specMode == MeasureSpec.EXACTLY) { result = specSize; } else { //接着上面的说,如果系统指定宽/高的是wrap_content, // 那这个就是AT_MOST模式,在这里就必须给它指定一个默认值defaultValue,这样,就优化了代码, // 如果指定wrap_content,系统不知道该分配多大空间给它,于是就默认这个组件的宽/高充满父组件,这个显然不合理,很浪费资源的。 // 所以这里指定一个默认的最大值,就算组件没有内容,系统也知道最大应该给他多少空间,不会造成浪费 if (specMode == MeasureSpec.AT_MOST) { result = Math.min(defaultValue, specSize);//这里获得的specSize其实是父组件的size,所以要取二者之小 } } return result; }
Android读书笔记3:控件架构以及自定义控件
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。