ImageVerifierCode 换一换
格式:DOCX , 页数:15 ,大小:21.41KB ,
资源ID:19443073      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/19443073.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(Android View的绘制流程三部曲Word文档下载推荐.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

Android View的绘制流程三部曲Word文档下载推荐.docx

1、 系统是通过View的MeasureSpec来确定View的测量宽高的MeasureSpec是怎么来的?对于普通的View来说,其MeasureSpec由父容器的MeasureSpec和自身的LayoutParams共同确定。对于顶级View(DecorView),其MeasureSpec由窗口的尺寸和其自身的LayoutParams共同确定。我们回到performMeasure方法,来看看传入的参数childWidthMeasureSpec和childHeightMeasureSpec,这两个MeasureSpec是顶级View的,它们由窗口的尺寸和其自身的LayoutParams共同确定。

2、那它们又是怎么产生的?在ViewRootImpl的measureHierarchy方法中,有两行代码是这样的:childWidthMeasureSpec = getRootMeasureSpec(desiredWindowWidth, lp.width);childHeightMeasureSpec = getRootMeasureSpec(desiredWindowHeight, lp.height);getRootMeasureSpec方法获取到根View(DecorView)的MeasureSpec。传入的参数desiredWindowWidth和desiredWindowHeight是

3、屏幕的尺寸。lp.width 和lp.height都是MATCH_PARENT。那么探探getRootMeasureSpec方法,如下:private static int getRootMeasureSpec(int windowSize, int rootDimension) int measureSpec; switch (rootDimension) case ViewGroup.LayoutParams.MATCH_PARENT: / Window cant resize. Force root view to be windowSize. measureSpec = Measure

4、Spec.makeMeasureSpec(windowSize, MeasureSpec.EXACTLY); break; case ViewGroup.LayoutParams.WRAP_CONTENT: / Window can resize. Set max size for root view. measureSpec = MeasureSpec.makeMeasureSpec(windowSize, MeasureSpec.AT_MOST); default: / Window wants to be an exact size. Force root view to be that

5、 size. measureSpec = MeasureSpec.makeMeasureSpec(rootDimension, MeasureSpec.EXACTLY); return measureSpec;会转到MeasureSpec的makeMeasureSpec方法,而makeMeasureSpec方法就是将SpecSize和SpecMode包装成32位的int值。那makeMeasureSpec方法是怎么组装MeasureSpec的呢?如下:public static int makeMeasureSpec(IntRange(from = 0, to = (1 = 0) result

6、Size = childDimension; resultMode = MeasureSpec.EXACTLY; else if (childDimension = LayoutParams.MATCH_PARENT) / Child wants to be our size. So be it. resultSize = size; else if (childDimension = LayoutParams.WRAP_CONTENT) / Child wants to determine its own size. It cant be / bigger than us. resultMo

7、de = MeasureSpec.AT_MOST; / Parent has imposed a maximum size on us case MeasureSpec.AT_MOST: / Child wants a specific size. so be it / Child wants to be our size, but our size is not fixed. / Constrain child to not be bigger than us. / Parent asked to see how big we want to be case MeasureSpec.UNSP

8、ECIFIED: / Child wants a specific size. let him have it / Child wants to be our size. find out how big it should / be resultSize = View.sUseZeroUnspecifiedMeasureSpec ? 0 : size; resultMode = MeasureSpec.UNSPECIFIED; / Child wants to determine its own size. find out how / big it should be /noinspect

9、ion ResourceType return MeasureSpec.makeMeasureSpec(resultSize, resultMode);经过了getChildMeasureSpec方法,子元素的MeasureSpec也诞生了。这个方法代码虽然长长的,但逻辑并不复杂,就是根据父容器的MeasureSpec和子元素的LayoutParams来组装子元素的MeasureSpec。所以说普通View的MeasureSpec由父容器的MeasureSpec和自身的LayoutParams共同决定。那么现在已经搞定了MeasureSpec,跟进performMeasure方法看看到底Vie

10、w的测量过程是怎样的。View的测量performMeasure方法源码如下:private void performMeasure(int childWidthMeasureSpec, int childHeightMeasureSpec) Trace.traceBegin(Trace.TRACE_TAG_VIEW, measure); try mView.measure(childWidthMeasureSpec, childHeightMeasureSpec); finally Trace.traceEnd(Trace.TRACE_TAG_VIEW);转到了View的measure方法,

11、如下:public final void measure(int widthMeasureSpec, int heightMeasureSpec) /代码省略 final boolean forceLayout = (mPrivateFlags & PFLAG_FORCE_LAYOUT) = PFLAG_FORCE_LAYOUT; if (forceLayout | needsLayout) / first clears the measured dimension flag mPrivateFlags &= PFLAG_MEASURED_DIMENSION_SET; resolveRtlPr

12、opertiesIfNeeded(); int cacheIndex = forceLayout ? -1 : mMeasureCache.indexOfKey(key); if (cacheIndex 0 | sIgnoreMeasureCache) / measure ourselves, this should set the measured dimension flag back onMeasure(widthMeasureSpec, heightMeasureSpec); mPrivateFlags3 &= PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;

13、mOldWidthMeasureSpec = widthMeasureSpec; mOldHeightMeasureSpec = heightMeasureSpec; mMeasureCache.put(key, (long) mMeasuredWidth) 32 | (long) mMeasuredHeight & 0xffffffffL); / suppress sign extension可以看到View的measure方法是带final的,不允许子类重写。经过一系列的处理,会转到onMeasure方法,那就跟进View的onMeasure方法探探:protected void onMe

14、asure(int widthMeasureSpec, int heightMeasureSpec) setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec), getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);调用了setMeasuredDimension将测量的宽高设置进去,好像很简单的说。getDefaultSize方法用于获取测量宽高,源码如下:public static int getDefaultSiz

15、e(int size, int measureSpec) int result = size; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); result = size; result = specSize; return result;其实内部逻辑是很简单的,从measureSpec中取出specMode和specSize,然后就是AT_MOST和EXACTLY的情况下,都返回specSize,这个specSize就是测量的值了。以上就是Vie

16、w的测量过程。补充:对于TextView、Button、ImageView等,它们都是重写了onMeasure方法的,可以阅读一下它们的onMeasure方法源码ViewGroup的测量那么接下来是ViewGroup的测量过程,ViewGroup中是没有重写onMeasure方法的,为什么ViewGroup不像View一样对其onMeasure方法做统一的实现呢?我们可以想一下的,怎么能定义出一个符合多种ViewGroup的onMeasure方法呢?很显然LinearLayout和RelativeLayout的onMeasure方法实现是不一样的。所以需要由子类去实现,这也是很合理的。View

17、Group除了完成自身的测量,还会遍历子元素,如此循环完成整棵视图树的测量过程。在ViewGroup中定义了一个measureChildren方法去遍历子元素,如下:protected void measureChildren(int widthMeasureSpec, int heightMeasureSpec) final int size = mChildrenCount; final View children = mChildren; for (int i = 0; i +i) final View child = childreni; if (child.mViewFlags &

18、VISIBILITY_MASK) != GONE) measureChild(child, widthMeasureSpec, heightMeasureSpec);会转到measureChild方法中去测量子元素。protected void measureChild(View child, int parentWidthMeasureSpec, int parentHeightMeasureSpec) final LayoutParams lp = child.getLayoutParams(); mPaddingLeft + mPaddingRight, lp.width); mPadd

19、ingTop + mPaddingBottom, lp.height);就这样,ViewGroup将measure过程传递到了子元素。如此反复完成整棵视图树的绘制。以上就是ViewGroup的测量过程,至此,View的测量过程已经分析结束。当measure过程完成后,就可以调用getMeasuredWidth/getMeasuredHeight方法来获取测量宽高了。理解ViewGroup的测量,可以阅读下LinearLayout的onMeasure方法源码。layout过程在performLayout方法中转到layout方法来完成View布局过程。那就来看看View的layout方法,如下:

20、public void layout(int l, int t, int r, int b) if (mPrivateFlags3 & PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT) ! onMeasure(mOldWidthMeasureSpec, mOldHeightMeasureSpec); int oldL = mLeft; int oldT = mTop; int oldB = mBottom; int oldR = mRight; boolean changed = isLayoutModeOptical(mParent) ? setOpticalFrame(l, t, r, b) :

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1