Android 自定义View基础,View架构,测量,绘制,事件拦截(基于《Android群英传》)

本文深入探讨了Android的视图架构,包括View视图树的构成、UI界面的全屏显示、视图的测量与绘制过程,以及自定义View的实现方法。同时,详细分析了事件拦截机制,阐述了事件传递的原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android 控件架构

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

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

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

  

UI界面架构图

界面的全屏显示

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时,事件传递如图:

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

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

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

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

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sunbofiy23

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值