Android自定义View探索(一)—生命周期

  • 时间:
  • 浏览:4

再来瞅一眼源码:

测量过程刚开始后,视图的大小就将会测量好了,接下来却说layout的过程了。正如其名字所描述的一样,你太满 太满 辦法 是用于给视图进行布局的,也却说选取视图的具体位置。

在绘图时时需明确五个核心的东西(basic components):

5.View生命周期:onMeasure

获取SpecSize

由此可见,视图大小的控制是由父视图、布局文件、以及视图太满 太满 一起完成的,父视图会提供给子视图参考的大小,开发人员可不可以在XML文件中指定视图的大小,最后视图太满 太满 才会选取最终的大小。

看看源码为什么会么会么解释的:

可用表格来规整各一下MeasureSpec的生成:

3.View生命周期:onFinishInflate

getMeasureWidth()辦法 在measure()过程刚开始后就可不可以获取到了,而getWidth()辦法 要在layout()过程刚开始可不可以够获取到。在太满 太满 繁复将会极端的具体情况下系统会多次执行measure过程,太满 太满 在onMeasure()中去获取View的测量大小得到的是一五个多不准确的值。为了解决该具体情况,最好在onMeasure()的下一阶段即onLayout()中去获取View的宽高。

布局文件:

onSizeChanged是在布局文件中自定义View的大小指在改变时被调用。五个参数依次代表变化以后的宽高以及变化以后的宽高。在onMeasure辦法 刚开始以后第一次进行调用,将测量的宽高作为前一五个多参数,0作为后一五个多默认参数。

onLayout是在layout辦法 中指定子View的大小和位置。我我嘴笨 却说ViewGroup会调用onLayout()决定子View的显示位置。其中五个参数l, t, r, b分别表示子View相对于父View的左、上、右、下的坐标。

子View的MeasureSpec由其父容器的MeasureSpec和该子View太满 太满 的布局参数LayoutParams一起决定。

时需注意的是,在setMeasuredDimension()辦法 调用以后,大伙儿儿儿能够使用getMeasuredWidth()和getMeasuredHeight()来获取视图测量出的准确的深度图与深度图。

二.结果分析

写在前面:

以后零零散散写过两篇自定义View的文章,当时却说为了模仿实现某个好看的效果,并这么 深入学习过,太满 太满 大难题还是一知半解。你太满 太满 系列的博客主要记录我人及 学习自定义View的过程以及心得。

MeasureSpec.EXACTLY :父视图希望子视图的大小是specSize中指定的大小,在该模式下,View的测量大小即为SpecSize。

int specSize = MeasureSpec.getSize(measureSpec)

MeasureSpec.UNSPECIFIED:父视图不对子视图施加任何限制,子视图可不可以得到任意你要的大小,表示子布局你要多大就多大。你太满 太满 模式一般用作Android系统内部人员,将会ListView和ScrollView等滑动控件,很少使用。

通过太满 太满 五个多值生成新的MeasureSpec

1.Activity生命周期:onCreate

第五步:绘制当前视图在滑动时的边框渐变效果,通常大伙儿儿儿是不时需解决你太满 太满 步的:If necessary, draw the fading edges and restore layers

瞅一眼源码:

第二步:保存当前画布的堆栈具体情况并在该画布上创建Layer用于绘制View在滑动时的边框渐变效果,通常具体情况下大伙儿儿儿不时需解决你太满 太满 步:If necessary, save the canvas’ layers to prepare for fading。

1.MeasureSpec封装了父布局传递给子View的布局要求

参考资料:

Android视图绘制流程完正解析,带你一步步深入了解View(二)

继续看看源码是为什么会么会么解释的:

从上边这张图片中大伙儿儿儿可不可以获取到太满 太满 重要的信息:

2. MeasureSpec可不可以表示宽和高

MeasureSpec是一五个多32位的int数据,其中高2位代表SpecMode即太满 太满 测量模式,低30位为SpecSize代表在该模式下的规格大小.

可不可以通过如下辦法 分别获取太满 太满 五个多值:

自定义View系列教程02–onMeasure源码详尽分析

Activity代码:

8.View生命周期:onDraw

任何一五个多视图有的是要经过非常科学的绘制流程可不可以够显示出来的,每一五个多视图的绘制过程我我嘴笨 却说一五个多完正的生命周期,大伙儿儿儿从这里刚开始入手,一起学习自定义View。

第三步:绘制View的内容:Draw view’s content。你太满 太满 步是整个draw阶段的核心,在此会调用onDraw()辦法 绘制View的内容。 以后大伙儿儿儿在分析layout的以后发现onLayout()辦法 是一五个多抽象辦法 ,具体的逻辑由ViewGroup的子类去实现。与之这类,在此onDraw()是一五个多空辦法 ;将会每个View所要绘制的内容不同,太满 太满 时需由具体的子View去实现人及 不同的需求。

当Activity在onCreate加载界面布局资源的以后,大伙儿儿儿自定义的View会在xml文件中被加载,而且 调用构造函数 MyView(Context context, AttributeSet attrs)来加载自定义View。

用有哪些工具画?

你太满 太满 小大难题很简单,大伙儿儿儿时时需一支画笔(Paint)来绘图。

当然,大伙儿儿儿可不可以选取不同颜色的笔,不同大小的笔。

把图画在哪里呢?

大伙儿儿儿把图画在了Bitmap上,它保存了所绘图像的各个像素(pixel)。

也却说说Bitmap承载和呈现了画的各种图形。

画的内容?

根据我人及 的需求画圆,画直线,画路径。

为什么会么会么画?

调用canvas执行绘图操作。

比如,canvas.drawCircle(),canvas.drawLine(),canvas.drawPath()将大伙儿儿儿时需的图像画出来。

3 MeasureSpec由size(大小)和mode(模式)组成

MeasureSpec.AT_MOST:父容器未能检测出子View所时需的精确大小,而且 指定了一五个多可用大小即specSize ,在该模式下,View的测量大小这么 超过SpecSize

6.View生命周期:onSizeChanged

第六步:绘制View的滚动条:Draw decorations (scrollbars for instance)

我人及 蹩脚的英语水平打上去网上的太满 太满 解释,我嘴笨 另一五个多理解还是比较靠谱的:

onFinishInflate是在自定义View中所有的子控件均被映射成xml后调用。另一五个多View就完成了初始准备工作,Activity也完成了对应布局资源的加载。

第一步:绘制背景:Draw the background

一.准备工作

关于绘制View的内容,这里就太满 做讨论,以后实战中根据实际具体情况来进行完正的分析,继续下一五个多生命周期。

至此,大伙儿儿儿将会经历了一次完正的自定义View的生命周期,接下来却说应用到实际项目中,希望能对你有所帮助,下一篇再见~~~

4.View生命周期:onAttachedToWindow

int specMode = MeasureSpec.getMode(measureSpec)

作为自定义View三部曲的第一步,onMeasure辦法 有着极其重要的作用,太满 太满 深入理解其中原理对大伙儿儿儿以后自定义View开发有着很大的帮助。

自定义View代码:

SpecMode一共有太满 太满 :

MeasureSpec.UNSPECIFIED,MeasureSpec.EXACTLY , MeasureSpec.AT_MOST , 大伙儿儿儿依次看看次责测量模式代表有哪些意思:

int measureSpec=MeasureSpec.makeMeasureSpec(size, mode);

9.View生命周期:onWindowFocusChanged

2.View生命周期:onCreate

当设置View的参数等于MATCH_PARENT的以后,MeasureSpec的specMode就等于EXACTLY,当设置View的参数等于WRAP_CONTENT的以后,MeasureSpec的specMode就等于AT_MOST。而且 MATCH_PARENT和WRAP_CONTENT时的specSize有的是等于windowSize的,也就因为 着根视图一个劲会充满全屏的。太满 太满 自定义View在重写onMeasure()的过程中应该手动解决View的宽或高为wrap_content的具体情况。

看看源码的解释:

onAttachedToWindow是在将view绑定到activity所在window时调用,附加到window后,多多线程 运行刚开始进行自定义View的绘制。

MeasureSpec测量规范:

系统显示一五个多View,首先时需通过测量(measure)该View来获取其长和宽从而选取显示该View时时需多大的空间。在测量的过程中MeasureSpec贯穿全程,发挥着不可或缺的作用,先瞅一眼源码:

源码是另一五个多告诉大伙儿儿儿的:

很简单的代码,整个布局文件上边一五个多自定义View,进入你太满 太满 界面,而且 返回。依次打印各个生命周期,大伙儿儿儿看一下打印的结果:

onDraw是真正地刚开始对视图进行绘制。

在Andorid官方文档中将该过程概况成了六步:

Activity生命周期的第一五个多辦法 ,表示此Activity正在被创建,这里大伙儿儿儿主要进行太满 太满 初始化的工作。比如调用setContentView()辦法 去加载界面布局资源。

经过测量得出的子View的MeasureSpec是系统给出的一五个多期望值(参考值),大伙儿儿儿也可摒弃系统的你太满 太满 测量流程,直接调用setMeasuredDimension( )设置子View的宽和高的测量值。

第四步:调用dispatchDraw()绘制View的子View:Draw children

7.View生命周期:onLayout

获取specMode

判断view是与非 获取焦点,参数hasWindowFocus 对应返回true 和false 可不可以用来判断view是与非 进出后台。第一次进入当前Activity的以后,返回true,返回上一五个多Activity,返回了false。