• 2011-06-14

    [Code] Android备忘6 - 各种兼容性bug - [Code]

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://www.blogbus.com/sgzxy-logs/136399659.html

    1. 在2.1以下版本,如果对某ViewGroup进行setDrawingCacheEnabled(true),则该ViewGroup中任何child的动画都将无法显示(或者说只刷新了第一帧,然后就不刷新了)。在2.1及以上版本无此问题

    原因:对比2.0和2.1版本的View源码,可以发现在buildDrawingCache这一方法的最后一段有改动:

    2.0源码:

                mPrivateFlags |= DRAWN;

                // Fast path for layouts with no backgrounds
                if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) {
                    if (ViewDebug.TRACE_HIERARCHY) {
                        ViewDebug.trace(this, ViewDebug.HierarchyTraceType.DRAW);
                    }
                    mPrivateFlags &= ~DIRTY_MASK;
                    dispatchDraw(canvas);
                } else {
                    draw(canvas);
                }

                canvas.restoreToCount(restoreCount);

                if (attachInfo != null) {
                    // Restore the cached Canvas for our siblings
                    attachInfo.mCanvas = canvas;
                }
                mPrivateFlags |= DRAWING_CACHE_VALID;

    2.1源码:

                mPrivateFlags |= DRAWN;
                mPrivateFlags |= DRAWING_CACHE_VALID;

                // Fast path for layouts with no backgrounds
                if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) {
                    if (ViewDebug.TRACE_HIERARCHY) {
                        ViewDebug.trace(this, ViewDebug.HierarchyTraceType.DRAW);
                    }
                    mPrivateFlags &= ~DIRTY_MASK;
                    dispatchDraw(canvas);
                } else {
                    draw(canvas);
                }

                canvas.restoreToCount(restoreCount);

                if (attachInfo != null) {
                    // Restore the cached Canvas for our siblings
                    attachInfo.mCanvas = canvas;
                }

    也就是mPrivateFlags |= DRAWING_CACHE_VALID;这一句位置的错误导致了2.1以下的bug。为什么呢,你只要debug跟踪一下便会明白,在dispatchDraw这一方法中,特别有一段代码来处理child要进行animation的情况。当child要进行animation,则会把parent进行invalidate(),使parent会不断刷新。而2.0的代码中,parent的invalidate虽然执行了,但其效果又被最后一句mPrivateFlags |= DRAWING_CACHE_VALID给抹去了,故而产生了上述的bug情况。

    分享到:

    历史上的今天: