Android 控件架构

Android View 视图 可以理解为一棵树,这个树有主干,有分支,有树叶,我们把ViewParent可以理解为树的主干,把ViewGroup理解为分支,每一个分支上可能都会有树叶,而树叶就是View

通常在Activity当中,我们使用findViewById()方法,以树的深度优先遍历来查找视图树里的元素,

View视图树如下所示(绘图工具使用的是ProcessOn,挺好的一个在线绘图工具)

  

android树形文件目录 android view树_android树形文件目录

UI界面架构图

android树形文件目录 android view树_事件拦截机制_02

界面的全屏显示

requestWindowFeature(Window.FEATURE_NO_TITLE)来设置全屏显示,这个方法的调用一定要在setContentView()前。

界面的绘制

当程序在onCreate()方法中调用setContentView()方法后,ActivityManageService会回调onResume()方法,此时系统才会把整个DecorView添加到PhoneWindow中。

View的测量

View的测量在onMeasure()方法里重写,通过MeasureSpec类,测量的模式分为EXACTLY(固定宽度,默认是),AT_MOST(最大),UNSPECFIED(不指定)

onMeasure()的super.measure(width,height)源码实现会调用setMeasureDimension(),我们把自定义的宽高传给它,就可以实现View大小的自定义了。

自定义宽高的模板方法:height与width类似

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;

}

View的绘制

View的绘制我们可以用onDraw()来重写实现,两个重要的参数,Canvas画布,Paint 画笔

自定义View的绘制没有什么难点,主要是调用API函数,具体学习可以参考-自定义View大佬朱凯的扔物线_给高级Android工程师的进阶手册

事件拦截机制分析

事件冲突的造成的原因:多层ViewGroup,View嵌套

Android里的事件传递,处理,通过MotionEvent这一关键类,重写onTouchEvent()方法。

在MotionEvent这个类里,

有获取触摸点的坐标,可以通过event.getX()方法---基于组件左上角和event.getRawX()方法---基于屏幕左上角。

有点击事件的Action,MotionEvent.ACTION_DOWN(手指按下),MotionEvent.ACTION_MOVE(手指移动),MotionEvent.ACTION_UP(手指抬起)。

注意:自定义ViewGroup的时候,务必重写onLayout()方法,不然子View是不会显示的。

当点击红色的View时,事件传递如图:

android树形文件目录 android view树_android树形文件目录_03

当点击黄色的View时,事件传递如图所示:

android树形文件目录 android view树_android树形文件目录_04

不知道小伙伴有没有发现规律,点击外层黑色View应该是……,很简单,尝试着做一做,这个留给读者思考吧~

总之,事件传递由外层到内层,事件处理由内层到外层。

事件传递的返回值也很容易,True:拦截    False:不拦截

事件处理的返回值类似:True:处理,False:不处理

初始情况下,两种返回值都是 False