这是我参与「第四届青训营 」笔记创作活动的的第4天
这一节课老师通过很多源码来介绍最基础的原理, 源码的学习需要循序渐进,带着问题阅读即可。
一、基础UI组件
1.通用的属性
对应的包名:andriod.widget包名
(1)id:与Java对应
(2)大小:height()、width()
(3)位置:margin()、padding()内容和组间间距的关系。gravity(子元素在容器内的对齐方式)layout_gravity(组件相对于父容器的对齐方式)
注:手机屏幕的原点在左上角;
(4)使用:setLayoutParams()、setPadding()
2.特有的属性
文本框、图像框、复选框等组件额外的内容。
3.高级UI组件
高级UI组件多是ViewGroup、比常规UI组件有更多的功能, 常见组件之间有继承关系。
二、布局
解决组件的大小、位置和层级的关系。
1.LinearLayout
(1) 特点
排列方向、大小权重、分割线位置,用到时再查阅相关的代码。
(2) 应用场景
线性排列的场景。
2.RelativeLayout
(1) 特点
知道自己周围的组件分别是什么,相对的坐标(父容器或者兄弟组件)
(2) 应用场景
可以消除嵌套视图组件并使布局结构扁平化,从而提升性能,一个RelativeLayout可以替换多个LinearLayout,用于更加复杂的场景。
3.FrameLayout
(1) 特点
设置前景图像,设置前景图像的Gravity。
前景图像:永远处于FrameLayout最上层,不会被覆盖的图片。
(2) 应用场景
层级排列,层级布局的场景。
4.ConstraintLayout
(1)特点
与RelativeLayout对比,ConstraintLayout的设置更加严格,
RelativeLayout只有一般的相对位置,ConstraintLayout还有大小的约束。
(2)应用场景
通过约束组件位置排列组件,扩展布局方式, 所有视图均依据同级视图与父布局之间的关系进行布局。
三、布局页面如何渲染出来的
写布局文件、写布局文件、设置布局文件,
布局加载、布局解析、UI渲染。
1.源码中的一些函数
setContentView:创建了DecorView,最终由LayoutInflater来创建XML文件。
LayoutInflater:LayoutInflater解析了XML文件,并根据XML问看看生成了View实例,并将View实例添加到了其ViewGroup中。
creatView:根据XML中View类名来找到相应View,并将XML中的描述属性解析为AttributeSet,并作为第二个参数传给View构造器。
2.View的绘制流程
(1)页面绘制与Activity的生命周期对应关系
思考问题:为什么Activity在onResume()之后才显示
onCreate():setContentView:创建了DecorView,并将Layout中的View添加到DecorView中。
onResume():ActivityThread.handleResumeActivity()
① WindowManagerImpl.addView
② 创建ViewRootImpl
③ ViewRootImpl.setView
④ ViewRootImpl.requestLayout()触发页面绘制
(2) View绘制的关键方法
Measure:长宽
Layout:位置
Draw:形状
(3) Vsync信号
有大量组件需要绘制的时候出现的形状
UI渲染Thread:输入处理、动画、测量、布局、绘制、同步
RenderThread:sync同步、execute执行、getbuffer获取缓存区、issue命令、swap buffer 交换缓冲区
四、交互
1.交互的理解
Target:将触摸事件传递到某个具体View&处理的整个过程。 Action:触摸事件由哪个对象发出、经过哪些对象、最终到达哪个对象。
① 获取View的实例
② 添加相应的监听器
思考问题:通过Id找到Button的原因。
遍历查找,相等则return,需要知道触摸事件由哪个对象发出、经过哪些对象。
2.常用交互事件的监听器
所有的交互事件都来自于对屏幕触摸信号的处理,View.OnClickListener()等常用点击事件时是对交互事件的二次封装。
| 回调方法 | 使用场景 |
|---|---|
| onClick() | 用户轻触项目 |
| onLongClick() | 用户长按项目 |
| onFocusChange() | 使用导航栏或者轨迹球转动或离开项目时 |
| onKey() | 用户聚焦于某个项目时 |
| onTouch() | 用户执行可视化事件时 |
3.屏幕触摸事件——MotionEvent
(1) 事件解释
| 事件类型常量 | 含义说明 |
|---|---|
| ACTION_DOWN | 手指接触屏幕时产生此事件,多点触摸时表示第一个手指产生此事件。 |
| ACTION_UP | 手指离开屏幕产生此事件,多点触摸时只有最后一个手指离开屏幕时能产生此事件。 |
| ACTION_MOVE | 手指在屏幕上滑动,多点触摸时每一个手指产生此事件。 |
| ACTION_CANCEL | 一个事件提早终止的时候由系统自动产生此事件。 |
| ACTION_POINTER_DOWN | 多点触摸时才会产生此事件,除了第一个接触屏幕的手指外,其余手指接触屏幕时会产生此事件。 |
| ACTION_POINTER_UP | 多点触摸时才会产生此事件,除了最后一个离开屏幕的手指外,其余手指接触屏幕时会产生此事件。 |
Activity和View都有onTouchEvent(),用于处理触摸事件,用户触摸屏幕时,会回调视图上的onTouchEvent(),对于最终被识别为收拾的每个轻触事件序列,onTouchEvent()都会被多次触发。
(2)触摸事件分发
思考问题:点击位置有多个界面为什么响应其中某一个呢?
| Touch事件相关方法 | 功能描述 | Activity | ViewGroup | View |
|---|---|---|---|---|
| boolean dispatchTouchEvent | 事件分发 | yes | yes | yes |
| boolean onInterceptTouchEvent | 事件拦截 | no | yes | no |
| boolean onTouchEvent | 事件响应 | yes | yes | yes |
(3)事件处理流程 思考问题:点击事件是在点击up还是down时响应的呢? 在action_down的时候判断点击位置。 思路问题:同一次点击是否有可能调用两次Click函数? eg.Click和LongClick不会被执行,是两个互斥的函数
五、动画
1.帧动画
(1)作用对象 视图控件:如ImageView、TextView
(2)原理 与GIF的区别在于帧动画可以很方便的控制图片的播放序列,
(3)特点
使用简单,但是功能单一。
(4)应用场景
连续性动画。
2.补间动画
(1)作用对象
View视图
(2)原理
给定初值和终值,中间样式根由系统插值确定来完成完整的动画。
(3)特点
透明度动画、旋转、播放动画、平移动画。
(4)应用场景
转场动画、视频基础动画。
3.属性动画
(1)作用对象
任意Java对象
(2)原理
在指定时间间隔内不断通过值的改变将值赋给对象,在对象上实现动画效果。
(3)特点
适用性广,动画效果丰富。
4.总结
视图动画:只能改变View的视觉效果,无法改变View的属性,eg.视频效果上View的位置改变了,但是View还在原区域。
六、自定义View的实例
1.基本UI组件
可以使用Java或者xml文件创建,xml创建会更加灵活。
2.布局
布局一般需复写onMeasure函数,onSizeChanged视图大小发生改变时调用。
onLayOut继承自ViewGroup时必须复写,继承自View一般不用。
3.渲染
按需复写onDraw方法,用Paint:画笔Canvas:画布来绘制View
4.交互 需要复写onTouchEvent
| 交互事件 | 交互逻辑 |
|---|---|
| ACTION_DOWN | 手指接触屏幕时产生此事件,多点触摸时表示第一个手指产生此事件。 |
| ACTION_UP | 手指离开屏幕产生此事件,多点触摸时只有最后一个手指离开屏幕时能产生此事件。 |
| ACTION_MOVE | 手指在屏幕上滑动,多点触摸时每一个手指产生此事件。 |
| ACTION_CANCEL | 一个事件提早终止的时候由系统自动产生此事件。 |
5.动画
选择合适的动画类型;
按需启动动画、试时停止动画;
可利用AnimationListener来监听动画。
2.创建View
一个参数用Java代码中创建View
处理View的布局 特定场景的设置值