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

原文地址:https://www.cnblogs.com/guanxinjing/p/11558790.html

时间: 2024-11-06 08:21:23

Android开发 View的UI刷新Invalidate和postInvalidate的相关文章

50个Android开发人员必备UI效果源码[转载]

50个Android开发人员必备UI效果源码[转载] http://blog.csdn.net/qq1059458376/article/details/8145497 Android 仿微信之主页面实现篇Android 仿微信之界面导航篇Android 高仿QQ 好友分组列表Android 高仿QQ 界面滑动效果Android 高仿QQ 登陆界面Android 对Path的旋转效果的拓展Android高仿360安全卫士布局源码Android SlidingDrawer 滑动抽屉效果Androi

Android中View绘制流程以及invalidate()等相关方法分析

前言: 本文是我读<Android内核剖析>第13章----View工作原理总结而成的,在此膜拜下作者 .同时真挚地向渴望了解 Android 框架层的网友,推荐这本书,希望你们能够在Android开发里学到更多的知识 . 整个View树的绘图流程是在ViewRoot.java类的performTraversals()函数展开的,该函数做的执行过程可简单概况为 根据之前设置的状态,判断是否需要重新计算视图大小(measure).是否重新需要安置视图的位置(layout).以及是否需要重绘 (d

android中刷新Invalidate和postInvalidate的区别

Android中实现view的更新有两组方法,一组是invalidate,另一组是postInvalidate,其中前者是在UI线程自身中使用,而后者在非UI线程中使用. Android提供了Invalidate方法实现界面刷新,但是Invalidate不能直接在线程中调用,因为他是违背了单线程模型:Android UI操作并不是线程安全的,并且这些操作必须在UI线程中调用. Android程序中可以使用的界面刷新方法有两种,分别是利用Handler和利用postInvalidate()来实现在

Android之界面刷新(invalidate和postInvalidate使用)

Android中实现view的更新有两组方法,一组是invalidate,另一组是postInvalidate,其中前者是在UI线程自身中使用,而后者在非UI线程中使用. Android提供了Invalidate方法实现界面刷新,但是Invalidate不能直接在线程中调用,因为他是违背了单线程模型:Android UI操作并不是线程安全的,并且这些操作必须在UI线程中调用. Android程序中可以使用的界面刷新方法有两种,分别是利用Handler和利用postInvalidate()来实现在

Android中View绘制流程以及invalidate()等相关方法分析(转载的文章,出处在正文已表明)

转载请注明出处:http://blog.csdn.net/qinjuning 前言: 本文是我读<Android内核剖析>第13章----View工作原理总结而成的,在此膜拜下作者 .同时真挚地向渴望了解 Android 框架层的网友,推荐这本书,希望你们能够在Android开发里学到更多的知识 . 整个View树的绘图流程是在ViewRoot.java类的performTraversals()函数展开的,该函数做的执行过程可简单概况为 根据之前设置的状态,判断是否需要重新计算视图大小(mea

Android开发之自定义UI组件和属性

Android系统虽然自带了很多的组件,但肯定满足我们个性化的需求,所以我们为了开发方便,需要自定义Android的UI组件,以实现我们个性化的需求. 自定义组合控件的步骤: 1 .自定一个View,需要继承相对布局,线性布局等ViewGroup的子类.ViewGroup是一个其他控件的容器,能够乘放各种组件. 2 .实现父类的3个构造方法.一般需要在构造方法里始化初自定义布局文件. 一个参数构造方法:为new控件使用 两个参数的造方法:在调用布局文件使用 两个参数的造方法:传递带有样式的布局文

android开发之时钟UI

android中自带了时钟UI组件,分别为AnalogClock和DigitalClock,分别为模拟时钟与数字时钟.   1.AnalogClock    可以自定义表盘.时针与分针.如下,只需在xml文件中设置即可. <!-- 定义模拟时钟,并使用自定义表盘.时针图片 --> <AnalogClock android:layout_width="wrap_content" android:layout_height="wrap_content"

Android开发----PullRefreshLibrary下拉刷新上拉加载相关代码

Mainactivity public class MainActivity extends Activity { private String url = "http://apis.juhe.cn/goodbook/catalog?key=9d6ef8c31647a206e05fcaff70527182&dtype=xml";    private List<Xmlarray> list;    private ListView lv;    // 定义一个变量,

Android开发系列之UI开发

在app开发的过程中,我们会使用到大量的控件,了解各种控件的特性,熟练的使用它们是非常重要的,本篇会详细介绍几种常见控件的使用方法,废话不多说,直接上代码. 一.TextView 二.EditText 三.ImageView 四.ProgressBar 五.AlertDialog 六.详解四种基本布局 一个丰富的界面不仅需要有多个控件组成,更要选择合适的布局使各个控件有条不絮地摆放在界面上,让界面看起来更佳美观.android开发过程中主要有四种基本布局:LinearLayout.Relativ