View.requestLayout
参考:安卓高手之路之图形系统(6)requestLayout的流程
一、invalidate和postInvalidate
这两个方法都是在重绘当前控件的时候调用的。invalidate在UI线程中调用,postInvalidate在非UI线程中调用。因为android的UI线程是非线程安全的,所以在非UI线程中,需要使用postInvalidate来使View重绘。当然,Handler和invalidate配合使用,也可以达到目的,但是程序会比较繁琐。
二、requestLayout
如果View对应的位置已经发生了变化,原来被他覆盖的内容需要被显示出来。这时,如果只重新绘制当前View,已经起不到效果。这就需要requestLayout来实现重绘当前View和父View,甚至更上层的View,以此类推。
下面附上上面博客的关于requestLayout的调用过程的内容:
当一个View调用requestLayout的时候,会给当前的View设置一个FORCE_LAYOUT标记。由此向ViewParent请求布局。这样从这个View开始向上一直requestLayout。最终到达ViewRootImpl。ViewParent 就是当前的传输链。【参见职责链设计模式】
第一步。
ViewRootImpl发现请求了布局。那么就会调用measure方法。
measure方法确认当前View是否有FORCE_LAYOUT标记。
如果有,那么就会进行重新measure。并且设置标记LAYOUT_REQUIRED。
public final void measure(int widthMeasureSpec, int heightMeasureSpec) {
if ((mPrivateFlags & FORCE_LAYOUT) == FORCE_LAYOUT ||
widthMeasureSpec != mOldWidthMeasureSpec ||
heightMeasureSpec != mOldHeightMeasureSpec) {
// first clears the measured dimension flag
mPrivateFlags &= ~MEASURED_DIMENSION_SET;
if (ViewDebug.TRACE_HIERARCHY) {
ViewDebug.trace(this, ViewDebug.HierarchyTraceType.ON_MEASURE);
}
// measure ourselves, this should set the measured dimension flag back
onMeasure(widthMeasureSpec, heightMeasureSpec);
// flag not set, setMeasuredDimension() was not invoked, we raise
// an exception to warn the developer
if ((mPrivateFlags & MEASURED_DIMENSION_SET) != MEASURED_DIMENSION_SET) {
throw new IllegalStateException("onMeasure() did not set the"
+ " measured dimension by calling"
+ " setMeasuredDimension()");
}
mPrivateFlags |= LAYOUT_REQUIRED;
}
mOldWidthMeasureSpec = widthMeasureSpec;
mOldHeightMeasureSpec = heightMeasureSpec;
}
第二步。
在随后的layout方法中,会判断这个标记。如果这个标记为true。
那么就一定会调用onLayout.
onLayout调用后清理LAYOUT_REQUIRED标记。
layout调用之后,会清理掉FORCE_LAYOUT标记。
当然在上述过程中,影响到了兄弟或者是父亲View的大小, 那么也兄弟或者是父亲View也会调用layout/onLayout。不管其是否已经调用requestLayout。如果说指定的MeasureSpec为此也发生了变化,
那么measure/onMeasure也会被调用。
通过上述分析发现,只要调用了requestlayout, 那么measure和onMeasure,以及layout,onlayout,draw onDraw都会被调用。
在很多情况下,requestLayout是不需要被调用的。例如,我们把一个AbsoluteLayout里面的childView挪动一下位置。我们仅仅需要调用的可能就是重新布局当前AbsoluteLayout,然后调用invalidate方法进行重绘。而不是从当前View向上的整个View树形结构都要重新layout,onLayout,measure,onMeasure一次。
这个时候,怎么办?
一种方法是,直接调用onLayout。然后调用invalidate进行重绘。很明显可以提升绘制效率。由于父View的layout实现中对会通知布局的listener。但是由于无法得到listener,因此调用onlayout的时候无法对其进行通知,这也是这种实现的缺陷。
View.requestLayout的更多相关文章
- android自定义View (五)view.requestLayout() 与 invalidate()
一.要点 If in the course of processing the event, the view's bounds may need to be changed, the view wi ...
- Android View 深度分析requestLayout、invalidate与postInvalidate
前言 前几篇文章中,笔者对View的三大工作流程进行了详细分析,而这篇文章则详细讲述与三大工作流程密切相关的两个方法,分别是requestLayout和invalidate,如果对Viwe的三个工作流 ...
- 深入理解 Android 之 View 的绘制流程
概述 本篇文章会从源码(基于Android 6.0)角度分析Android中View的绘制流程,侧重于对整体流程的分析,对一些难以理解的点加以重点阐述,目的是把View绘制的整个流程把握好,而对于特定 ...
- View动画和属性动画
在应用中, 动画效果提升用户体验, 主要分为View动画和属性动画. View动画变换场景图片效果, 效果包括平移(translate), 缩放(scale), 旋转(rotate), 透明(alph ...
- 简单研究Android View绘制二 LayoutParams
2015-07-28 17:23:20 本篇是关于LayoutParams相关 ViewGroup.LayoutParams文档解释如下: LayoutParams are used by views ...
- Android动画主要包含补间动画(Tween)View Animation、帧动画(Frame)Drawable Animation、以及属性动画Property Animation
程序运行效果图: Android动画主要包含补间动画(Tween)View Animation.帧动画(Frame)Drawable Animation.以及属性动画Property Animatio ...
- View,viewgroup,viewstub总结
:first-child { margin-top: 0; } blockquote > :last-child { margin-bottom: 0; } img { border: 0; m ...
- [Android FrameWork 6.0源码学习] View的重绘过程之Layout
View绘制的三部曲,测量,布局,绘画现在我们分析布局部分测量部分在上篇文章中已经分析过了.不了解的可以去我的博客里找一下 View的布局和测量一样,都是从ViewRootImpl中发起,ViewRo ...
- Android ViewManager解读之requestLayout() 详解
尊重原创: http://blog.csdn.net/sk719887916/article/details/48464035 上篇<Android View 中invalidate() 你所不 ...
随机推荐
- QT 11 鼠标键盘事件添加
鼠标事件 void mousePressEvent(QMouseEvent *event); //单击 void mouseReleaseEvent(QMouseEvent *event); //释放 ...
- 虚拟机oom
解决: 重启服务器或者增加内存
- <数据结构与算法分析>读书笔记--运行时间计算
有几种方法估计一个程序的运行时间.前面的表是凭经验得到的(可以参考:<数据结构与算法分析>读书笔记--要分析的问题) 如果认为两个程序花费大致相同的时间,要确定哪个程序更快的最好方法很可能 ...
- zabbix学习-如何部署一个agent客户端
1. 部署一个agent客户端很简单,比如监控服务器本身 yum install zabbix-agent -y 2.配置文件位置: vim /etc/zabbix/zabbix-agendt.con ...
- DNS主从复制及区域传送
前言 DNS主从复制,就是将主DNS服务器的解析库复制传送至从DNS服务器,进而从服务器就可以进行正向.反向解析了.从服务器向主服务器查询更新数据,保证数据一致性,此为区域传送.也可以说,DNS区域传 ...
- u-boot全面分析
uboot主Makefile分析1 uboot住Makefile分析参考:https://www.2cto.com/kf/201607/522424.html uboot version确定(Make ...
- linux下文件共享的几种常用方式
1. python方式,做一个简单的服务器.默认是开启8000端口. > python -m SimpleHTTPServer 执行命令后,在浏览器上输入该机器IP+8000端口即可 2. sc ...
- CF11D A Simple Task 状压DP
传送门 \(N \leq 19\)-- 不难想到一个状压:设\(f_{i,j,k}\)表示开头为\(i\).结尾为\(j\).经过的点数二进制下为\(k\)的简单路总数,贡献答案就看\(i,j\)之间 ...
- Android下WPS打开Excel2007版也有问题
继上次解决微软office Android版Excel下载并打开Excel文件修改后(http://anforen.com/wp/2017/11/excel-android-mobile/),再上传出 ...
- Java 面试题 队列
Queue: 基本上,一个队列就是一个先入先出(FIFO)的数据结构 Queue接口与List.Set同一级别,都是继承了Collection接口.LinkedList实现了Deque接 口. Q ...