zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    第11组 Beta冲刺(1/5)
    第11组 Alpha事后诸葛亮
    第11组 Alpha冲刺(6/6)
    第11组 Alpha冲刺(5/6)
    第11组 Alpha冲刺(4/6)
    第11组 Alpha冲刺(3/6)
    毕设笔记
    软工实践个人总结
    第01组 Beta版本演示
    第01组 Beta冲刺(5/5)
  • 原文地址:https://www.cnblogs.com/guanxinjing/p/11558790.html
Copyright © 2011-2022 走看看