Android开发 View的UI刷新Invalidate和postInvalidate
Posted guanxinjing
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android开发 View的UI刷新Invalidate和postInvalidate相关的知识,希望对你有一定的参考价值。
Invalidate
正常刷新
/** * 使整个视图无效。如果视图可见, * @link #onDraw(android.graphics.Canvas) 调用此方法后将在后续的UI刷新里调用onDraw(android.graphics.Canvas)方法 * <p> * 必须从UI线程调用此方法。要从非UI线程调用,请调用@link #postInvalidate().*/ public void invalidate() invalidate(true); /** * This is where the invalidate() work actually happens. A full invalidate() * causes the drawing cache to be invalidated, but this function can be * called with invalidateCache set to false to skip that invalidation step * for cases that do not need it (for example, a component that remains at * the same dimensions with the same content). * * @param invalidateCache Whether the drawing cache for this view should be * invalidated as well. This is usually true for a full * invalidate, but may be set to false if the View‘s contents or * dimensions have not changed. * @hide */ public void invalidate(boolean invalidateCache) invalidateInternal(0, 0, mRight - mLeft, mBottom - mTop, invalidateCache, true);
一些解释
1.首先invalidate() 也是调用 invalidate(boolean invalidateCache) 这个方法的,只有设置为true时才会让这个View刷新
2.上面的注释已经说了invalidate()的刷新是必需在UI线程的
设置布局位置,重新调整View的刷新位置
/** * Mark the area defined by dirty as needing to be drawn. If the view is * visible, @link #onDraw(android.graphics.Canvas) will be called at some * point in the future. * <p> * This must be called from a UI thread. To call from a non-UI thread, call * @link #postInvalidate(). * <p> * <b>WARNING:</b> In API 19 and below, this method may be destructive to * @code dirty. * * @param dirty the rectangle representing the bounds of the dirty region * * @deprecated The switch to hardware accelerated rendering in API 14 reduced * the importance of the dirty rectangle. In API 21 the given rectangle is * ignored entirely in favor of an internally-calculated area instead. * Because of this, clients are encouraged to just call @link #invalidate(). */ @Deprecated public void invalidate(Rect dirty) final int scrollX = mScrollX; final int scrollY = mScrollY; invalidateInternal(dirty.left - scrollX, dirty.top - scrollY, dirty.right - scrollX, dirty.bottom - scrollY, true, false); /** * Mark the area defined by the rect (l,t,r,b) as needing to be drawn. The * coordinates of the dirty rect are relative to the view. If the view is * visible, @link #onDraw(android.graphics.Canvas) will be called at some * point in the future. * <p> * This must be called from a UI thread. To call from a non-UI thread, call * @link #postInvalidate(). * * @param l the left position of the dirty region * @param t the top position of the dirty region * @param r the right position of the dirty region * @param b the bottom position of the dirty region * * @deprecated The switch to hardware accelerated rendering in API 14 reduced * the importance of the dirty rectangle. In API 21 the given rectangle is * ignored entirely in favor of an internally-calculated area instead. * Because of this, clients are encouraged to just call @link #invalidate(). */ @Deprecated public void invalidate(int l, int t, int r, int b) final int scrollX = mScrollX; final int scrollY = mScrollY; invalidateInternal(l - scrollX, t - scrollY, r - scrollX, b - scrollY, true, false);
postInvalidate
这个方法可以非UI线程中调用
正常刷新
/** * <p>导致在事件循环的后续循环中发生无效。使用此选项使非UI线程中的View无效</p> * * <p>仅当此视图附加到窗口时,才能从UI线程*外部调用此方法。</p> * * @see #invalidate() * @see #postInvalidateDelayed(long) */ public void postInvalidate() postInvalidateDelayed(0);
改变位置后刷新
/** * <p>Cause an invalidate of the specified area to happen on a subsequent cycle * through the event loop. Use this to invalidate the View from a non-UI thread.</p> * * <p>This method can be invoked from outside of the UI thread * only when this View is attached to a window.</p> * * @param left The left coordinate of the rectangle to invalidate. * @param top The top coordinate of the rectangle to invalidate. * @param right The right coordinate of the rectangle to invalidate. * @param bottom The bottom coordinate of the rectangle to invalidate. * * @see #invalidate(int, int, int, int) * @see #invalidate(Rect) * @see #postInvalidateDelayed(long, int, int, int, int) */ public void postInvalidate(int left, int top, int right, int bottom) postInvalidateDelayed(0, left, top, right, bottom);
延迟刷新
/** * <p>导致在事件*循环的后续循环中发生无效。等待指定的时间。</p> * * <p>This method can be invoked from outside of the UI thread * only when this View is attached to a window.</p> * * @param delayMilliseconds the duration in milliseconds to delay the * invalidation by * * @see #invalidate() * @see #postInvalidate() */ public void postInvalidateDelayed(long delayMilliseconds) // We try only with the AttachInfo because there‘s no point in invalidating // if we are not attached to our window final AttachInfo attachInfo = mAttachInfo; if (attachInfo != null) attachInfo.mViewRootImpl.dispatchInvalidateDelayed(this, delayMilliseconds);
改变位置,并且延迟刷新
/** * <p>Cause an invalidate of the specified area to happen on a subsequent cycle * through the event loop. Waits for the specified amount of time.</p> * * <p>This method can be invoked from outside of the UI thread * only when this View is attached to a window.</p> * * @param delayMilliseconds the duration in milliseconds to delay the * invalidation by * @param left The left coordinate of the rectangle to invalidate. * @param top The top coordinate of the rectangle to invalidate. * @param right The right coordinate of the rectangle to invalidate. * @param bottom The bottom coordinate of the rectangle to invalidate. * * @see #invalidate(int, int, int, int) * @see #invalidate(Rect) * @see #postInvalidate(int, int, int, int) */ public void postInvalidateDelayed(long delayMilliseconds, int left, int top, int right, int bottom) // We try only with the AttachInfo because there‘s no point in invalidating // if we are not attached to our window final AttachInfo attachInfo = mAttachInfo; if (attachInfo != null) final AttachInfo.InvalidateInfo info = AttachInfo.InvalidateInfo.obtain(); info.target = this; info.left = left; info.top = top; info.right = right; info.bottom = bottom; attachInfo.mViewRootImpl.dispatchInvalidateRectDelayed(info, delayMilliseconds);
end
以上是关于Android开发 View的UI刷新Invalidate和postInvalidate的主要内容,如果未能解决你的问题,请参考以下文章
Android中刷新Invalidate和postInvalidate的区别
android: View, SurfaceView, GLSurfaceView, TextureView 区别与联系