首页
学习
活动
专区
圈层
工具
发布

动态添加的视图在invalidate()之后不调用onDraw

在Android开发中,动态添加的视图在调用invalidate()方法后不会立即调用onDraw()方法。invalidate()方法用于告知系统视图已经无效,需要重新绘制。但系统并不会立即重新绘制视图,而是将重新绘制的请求放入绘制队列中,在下一个绘制周期中进行处理。

具体来说,当我们调用invalidate()方法后,系统会将该视图添加到绘制队列中,并等待下一个绘制周期开始时进行处理。绘制周期通常在UI线程中进行,按照一定的规则进行调度。而onDraw()方法则是在绘制周期中被调用的,用于实际绘制视图内容。

因此,在调用invalidate()方法后,并不能立即保证视图会立即重新绘制。如果需要确保视图在调用invalidate()后立即重新绘制,可以使用postInvalidate()方法。postInvalidate()方法与invalidate()方法类似,但可以在非UI线程中调用,用于立即将视图的重新绘制请求发送到UI线程中。

对于解决动态添加视图在invalidate()之后不调用onDraw()的问题,可以考虑以下方法:

  1. 使用postInvalidate()方法代替invalidate()方法,确保在任何线程中都能立即调用重新绘制请求。
  2. 确保在调用invalidate()方法后,不会对视图进行过多的UI操作,以免阻塞UI线程,导致绘制周期延迟。
  3. 可以通过监听视图的某些状态变化,在状态变化时调用invalidate()方法,以触发重新绘制。

总结起来,动态添加的视图在invalidate()之后不会立即调用onDraw()方法,需要等待下一个绘制周期开始时才会进行处理。如果需要立即重新绘制视图,可以使用postInvalidate()方法。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

基于VC2019开始C++之第一个MFC程序(画图)

第一次编译生成的默认项目,之后得到下面的界面 点击VS2019的界面,“解决方案资源管理器” 到这里,项目建成,并且编译通过。...二、添加自定义的功能(以比较通用的画图为例) 点击资源视图,这里的控件将是后面需要操作的。 双击IDR_MAINFRAME,可以在这里面添加画图功能。...这里我们新建一个graph.cpp源文件 在graph.cpp中添加头文件 这里我们添加头文件pch.h和framework.h,并添加下面代码(为什么添加pch.h,因为即使后面选择了不预编译头文件...> graphList; 因为调用了list,所以在framework.h中添加 #include 这里要调用用OnRectangle()函数,之前生成的函数,我们现在添加下面的代码:...生成下面的图形,矩形可以移动,可拉伸 点击项目中的属性,在配置属性中选择高级,MFC使用 静态库,在编译一次,生成.exe可以其他电脑上不依赖动态库也能打开了。

4.1K30

Android面试刨根问底之常用源码篇(二):OkHttp, Retrofit,自定义View源码分析总结

内部类,disklrucache算法等 重点是不缓存非get的请求。...在服务端返回数据之后,OkHttp将原始的结果交给Retrofit,Retrofit根据用户的需求对结果进行解析。...创建接口实例,调用具体的网络请求 call同步/异步网络请求 处理服务器返回的数据 Retrofit网络通信八步骤 创建Retrofit实例 定义网络请求接口,并为接口中的方法添加注解 通过动态代理生成网络请求对象...静态 动态 在程序运行时创建的代理方式 无侵入增强 jdk动态代理 vs cglib jdk动态代理 只能为接口动态 InvocationHandler必须要实现 invoke的参数中获取参数 invoke...DecorView,而它是FrameLayout的子类,所以就会让其子视图绘制两次,所以onMeasure函数会先被调用两次。

1.4K00
  • Invalidate介绍

    1、Invalidate介绍  void Invalidate( BOOL bErase = TRUE );   该函数的作用是使整个窗口客户区无效。...视图类有一些例外,在视图类的OnPaint函数中调用了OnDraw函数,实际的重绘工作由OnDraw来完成。参数bErase为TRUE时,重绘区域内的背景将被擦除,否则,背景将保持不变。...调用Invalidate等函数后窗口不会立即重绘,这是由于WM_PAINT消息的优先级很低,它需要等消息队列中的其它消息发送完后才能被处理。...Delphi中的代码procedure TWinControl.Invalidate;begin Perform(CM_INVALIDATE, 0, 0);end;这个方法会使窗口重绘。...本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

    47210

    面试?看完这篇就够了-深入分析从点击应用图标到应用界面展示

    : //调用invalidate()方法,打印如下MyView onDraw:requestLayout 和 invalidate 最终都会调用到 ViewRootImpl 的 scheduleTraversals...总结requestLayout()和invalidate()都是Android中用于更新视图的方法,它们的区别如下:requestLayout():当视图的布局参数(如宽度、高度、位置等)发生变化时,需要调用...invalidate():当视图的内容(如颜色、文本等)发生变化时,需要调用invalidate()方法来重新绘制(draw)视图。...通常情况下,当视图的外观发生变化时,需要调用invalidate()方法。requestLayout()用于更新视图的布局参数,会触发整个视图树的测量、布局和绘制流程,性能开销较大。...invalidate()用于更新视图的内容,只会触发视图的绘制流程,性能开销较小。在实际开发过程中,需要根据视图的变化情况选择合适的方法来更新视图。

    41830

    基于VS2019开始C++之第一个MFC程序

    第一次编译生成的默认项目,之后得到下面的界面 点击VS2019的界面,“解决方案资源管理器” 到这里,项目建成,并且编译通过。...二、添加自定义的功能(以比较通用的画图为例) 点击资源视图,这里的控件将是后面需要操作的。 双击IDR_MAINFRAME,可以在这里面添加画图功能。...也可以在Ribbon里面添加画图功能 然后点击工具箱->RIbbon编辑器: 双击Ribbon下的面板控件 修改名称为形状,并添加一个按钮控件,修改名字为矩形 修改矩形的杂项,ID改为ID_RECTANGLE...list graphList; 因为调用了list,所以在framework.h中添加 #include 这里要调用用OnRectangle()函数,之前生成的函数...生成下面的图形,矩形可以移动,可拉伸 点击项目中的属性,在配置属性中选择高级,MFC使用 静态库,在编译一次,生成.exe可以其他电脑上不依赖动态库也能打开了。

    1.6K20

    android之View绘制

    在view中onDraw()是个空函数,也就是说具体的视图都要覆写该函数来实现自己的显示(比如TextView在这里实现了绘制文字的过程)。...,之后再有一个for循环对子视图进行遍历,来调用子视图的draw方法(实际为下边的drawChild());     (2)drawChild(),该方法用于具体调用子视图的draw方法,内部首先会处理视图动画...(也就是说视图动画是在这里处理的),之后调用子视图的draw()。    ...当视图调用invalidate()方法时,首先会将当前视图的DRAWN标志置位,之后有一个循环调用parent.invalidateChildinParent(),这样会导致从当前视图依次向上遍历直到根视图...ViewRoot,这个过程会将需要重绘的视图标记DRAWN置位,之后ViewRoot调用performTraversals()方法,完成视图的绘制过程。

    80890

    自定义View必备知识-View绘制流程

    (Canvas canvas) onDraw绘制自己,新建一个paint 在canvas上绘制自己的图形 绘制children (dispatchDraw)dispatchDraw会遍历调用所有子元素的...可以调用setEnable()方法来改变视图的可用状态,传入true表示可用,传入false表示不可用。 它们之间最大的区别在于,不可用的视图是无法响应onTouch事件的。...isFocused() 当前视图是否获得焦点 通常情况下有两种方法可以让视图获得焦点,即通过键盘的上下左右键切换视图,以及调用requestFocus()方法。...还需要尽可能的减少onDraw被调用的次数,大多数时候导致onDraw都是因为调用了invalidate().因此请尽量减少调用invaildate()的次数。...如果可能的话,尽量调用含有4个参数的invalidate()方法而不是没有参数的invalidate()。没有参数的invalidate会强制重绘整个view。

    1.8K30

    自定义View(九)-View的工作原理- View的layout()和draw()

    绘制当前视图的内容。 绘制当前视图的子视图的内容。 绘制当前视图在滑动时的边框渐变效果。 绘制当前视图的滚动条。 在一般情况下2和5我们在自定义View时是不会去修改的。...3.绘制视图View的内容onDraw 第三步是调用onDraw()方法绘制内容。发现是一个空的方法,也就是说所有View继承View的控件都要重写这个方法来实现对自己内容的绘制。...View绘制6步分析.png 我们在来总结几个关于View绘制相关的知识点: 父类View绘制主要是绘制背景,边框渐变效果,进度条,View具体的内容绘制调用了onDraw方法,通过该方法把View内容的绘制逻辑留给子类去实现...onDraw,dispatchDraw区别 View还是ViewGroup对它们俩的调用顺序都是onDraw()->dispatchDraw() 在ViewGroup中,当它有背景的时候就会调用onDraw...()都会被调用的,所以我们无论把绘图代码放在onDraw()或者dispatchDraw()中都是可以得到效果的,但是由于dispatchDraw()的含义是绘制子控件,所以原则来上讲,在绘制View控件时

    3.1K20

    android开关按钮

    可以查看官方文档,之后继承CompuundButton,在布局的动画和显示上调用onDraw(Canvas canvas)重画既可以,如果想要加入拖动属性,那么在该VIEW内重写触摸事件onTouchEvent...进行配置属性(源码角度)     具体的这边不贴代码了,可以查看DEMO里面的,都有注释。...注意:由于状态切换等,enabled属性改变等,是你自定义的方法内的话,你必须自己去调用invalidate();方法,去让UI判断是否有更改并做出相应的变化。...UI是否需要变化,之后在UI方法onDraw(Canvas canvas)中调用: android.graphics.Canvas.saveLayerAlpha(RectF bounds, int alpha...由于目前对于重写VIEW的onDraw方法的了解不是很深入,所以这里的DEMO中的几个方法都是查看网络之后加上自己的优化和注释演变过来,等这一块深入了后在重写写一篇关于这个的感受和使用说明。

    4.5K80

    SwitchButton 开关按钮 的多种实现方式

    可以查看官方文档,之后继承CompuundButton,在布局的动画和显示上调用onDraw(Canvas canvas)重画既可以,如果想要加入拖动属性,那么在该VIEW内重写触摸事件onTouchEvent...进行配置属性(源码角度)     具体的这边不贴代码了,可以查看DEMO里面的,都有注释。...注意:由于状态切换等,enabled属性改变等,是你自定义的方法内的话,你必须自己去调用invalidate();方法,去让UI判断是否有更改并做出相应的变化。...UI是否需要变化,之后在UI方法onDraw(Canvas canvas)中调用: android.graphics.Canvas.saveLayerAlpha(RectF bounds, int alpha...由于目前对于重写VIEW的onDraw方法的了解不是很深入,所以这里的DEMO中的几个方法都是查看网络之后加上自己的优化和注释演变过来,等这一块深入了后在重写写一篇关于这个的感受和使用说明。

    3.7K70

    2014-10-31Android学习------setContentView(View view)--------GIF动画实现

    void onDraw(Canvas canvas) { //TODO 处理你想要干的事,就是你想在画布上显示什么东西,这里都可以你自己去写,去设置 } } } 一.这个模式很简单,下面我们要处理的就是如何去实现动态...GIF图像的播放了: 要想实现动态图片,我们必须要用到一个类,Movie,这个类就是在Android中解决GIF动画非常方便的一个选择 那么如果我们知道需要这个类,怎么去创建这个 Movie类呢,那么我们需要先去看看...肯定就是将这个信息展示给人看对不,也就是将这个信息画到视图上对不?...对的 接下来我们就需要去处理 onDraw(Canvas canvas)这个函数了 在实现一个动画的时候,我们还需要掌握一些 知识 动画一般采用帧形式播放,这就决定我们需要去考虑播放的时间,每帧播放的长度...哈哈,视图需要更新啊,由于是动画,这帧放完了,赶紧放下帧,那么就涉及到视图的更新了,加一句代码就可以 invalidate(); 至此 整个流程就清晰了,下面贴上系统的代码和展示图片: import

    31830

    Android高频面试专题 - 提升篇(二)View绘制流程

    1、View绘制的起点 在提升篇(一)中提过,当建立好了decorView与ViewRoot的关联后,ViewRoot类的requestLayout()方法会被调用,以完成应用程序用户界面的初次布局。...和postInvalidate区别 二者都会出发刷新View,并且当这个View的可见性为VISIBLE的时候,View的onDraw()方法将会被调用,invalidate()方法在 UI 线程中调用...postInvalidate() 方法在非 UI 线程中调用,通过Handler通知 UI 线程重绘。...当view确定自身已经不再适合现有的区域时,该view本身调用这个方法要求parent view(父类的视图)重新调用他的onMeasure、onLayout来重新设置自己位置。...10、onDraw() 和dispatchDraw()的区别 绘制View本身的内容,通过调用View.onDraw(canvas)函数实现 绘制自己的孩子通过dispatchDraw(canvas)实现

    10K31

    Android 自定义View小结(重于理解,不作为教程)

    其实LayoutInflater技术广泛应用于需要动态添加View的时候,通过addview方法, 添加某一个子View 比如在ScrollView和ListView中,经常都可以看到LayoutInflater..., 在重写onMesure方法时,内部要调用setMeasuredDimension 方法之后,我们才可以调用getMeasuredWidth()和getMeasureHeight()来获取试图测量出的宽高..., 在onLayout()过程结束后,我们就可以调用getWidth()方法和getHeight()方法来获取视图的宽高了。..., 有一个状态选择器(selector 可以设置背景,根据是否处于pressed状态去动态改变) 5.pressed 表示当前视图是否处于按下状态,可以调用seetPressed()方法来对这一状态进行改变...3.控件的自绘及组合、继承 3.1 控件的自绘 这个无需多讲, 其实控件的自绘,就是视图全部由我们自己去绘制, 最重要的就是onDraw方法,,调用invalidate()方法会导致视图进行重绘,因此onDraw

    42010

    2014-10-27Android学习------布局处理(七)------26个字母的布局列表的监听事件处理-----城市列表应用程序

    :在屏幕中拖动:该方法还负责处理触控笔在屏幕上滑动的事件,同样是调用MotionEvent.getAction()方法来判 断动作值是否为MotionEvent.ACTION_MOVE再进行处理。...(b[c]);//处理这个字母 显示 choose = c;//记住当前被选择中的字母 invalidate();//更新View,在UI线程自身中使用 } } break; case...();,它马上就又执行了onDraw()函数,就是更新视图 接着又是执行dispatchTouchEvent()函数,触摸类型是:MotionEvent.ACTION_UP 接下来又是执行了onDraw...()函数,就是更新视图,等待用户的继续操作 从这个输出logcat里面我们可以看到:activity可以去调用dispatchTouchEvent()函数,而且监听事件中是这个函数第一个执行,然后获取监听事件的类型...,接下来就去调用onTouchEvent()函数, 我们再来看看拖动事件的执行过程: 好了 时间有限 ,今天就写到这里,具体的原理下次有机会再讲了,这个类写好之后,我们以后需要用这样的一个widget

    58630

    Android进阶之绘制-自定义View完全掌握(四)

    注意,一定要重写带两个参数的构造方法,因为如果我们在布局文件使用该类,将会用这个构造方法实例该类,如果没有就崩溃。 介绍一下一个控件从创建到显示过程中的主要方法。...指定位置,通过layout方法,需要去重写onLayout方法 指定控件的位置,一般View不用重写该方法,只有是ViewGroup的时候才需要去重写它 绘制视图,通过draw方法,需要去重写onDraw...我们在绘制第二张图的时候是距离左边距为0,而此时我们已经计算出了开启状态需要距离左边的边距,所以,我们只需这样修改 canvas.drawBitmap(slidingBitmap,slidLeftMax...这样就使得开关处于开启的状态了。既然如此,那我们就可以通过动态地改变左边距的值从而间接地控制开关状态。 我们重新修改MyToggleButton类的代码。...这个时候,虽然不会出现上次的尴尬情况,但是,这里又有一个问题,就是我在滑动的时候,它总是往我滑动的反方向跑,我想让它向右滑动,可它偏偏就要去左边,这显然也是不行的吧。

    58620

    关于RecyclerView的notifyDataSetChanged

    在很久以前,总觉得ListView的notifyDataSetChanged之类的方法很神奇,数据更新后,调用一下,视图就变了… 不过自从知道观察者模式以后就没感觉那么神奇了,反而对View的绘制测量一系列精细的计算叹为观止...我们知道,setAdpater视图确实是有所变化的;我们也知道,requestLayout方法和invalidate方法有所不同,invalidate只会调用onDraw,而requestLayout则会...onMeasure、onLayout、onDraw都调用。...requestLayout和invalidate都会调用父类视图的同名方法,最终到达ViewRootImpl中的同名方法,而ViewRootImpl会根据一些标记来决定是否执行measure/layout...至于hasPendingUpdates,可以理解为添加删除等操作的标记数量,默认情况下是为0的。 所以requestLayout是得以顺利执行的,那么视图变化就变得顺理成章了。

    84350

    View绘制流程

    对于每个视图的 height 和 width,你有以下选择: 具体值 MATCH_PARENT 表示子视图希望和父视图一样大(不包含 padding 值) WRAP_CONTENT 表示视图为正好能包裹其内容大小...在我们在自定义视图的时候,不需要关心系统复杂的 Measure 过程的,只需调用setMeasuredDimension()设置根据 MeasureSpec 计算得到的尺寸即可,你可以参考 ViewPagerIndicator...然后调用每一个子视图的layout(l, t, r, b)函数,来确定每个子视图在父视图中的位置。...在自定义的视图中,也不应该复写该方法,而是复写 onDraw(Canvas) 方法进行绘制,如果自定义的视图确实要复写该方法,那么请先调用 super.draw(canvas)完成系统的绘制,然后再进行自定义的绘制...invalidate() 请求重绘 View 树,即 draw 过程,假如视图发生大小没有变化就不会调用layout()过程,并且只绘制那些调用了invalidate()方法的 View。

    91150
    领券