安卓绘制缓存

16
请解释一下在Android中绘图缓存是如何工作的。我正在实现一个自定义的View子类,希望我的绘图能够被系统缓存。在View构造函数中,我调用了什么方法?
setDrawingCacheEnabled(true);

然后在 draw(Canvas c) 方法中,我执行:

    Bitmap cac = getDrawingCache();
    if(cac != null)
    {
        c.drawBitmap(cac, 0, 0, new Paint());
        return;
    }

尽管我调用了getDrawingCache(),但它对我返回了null。我的draw()既没有从setDrawingCacheEnabled()中被调用,也没有从getDrawingCache()中被调用。请问我做错了什么?


可能是 https://dev59.com/8HE85IYBdhLWcg3wXCIv 的重复问题。 - Hasturkun
2
不同之处在于一个涉及请求系统提供的子视图缓存,而另一个涉及在您自己的视图中构建它。 - Seva Alekseyev
这个会起作用 - https://dev59.com/3GbWa4cB1Zd3GeqPVUw8 - Ron
2个回答

9

在ViewConfiguration类中,有一个关于绘制缓存大小的硬性限制。我的视图超过了允许缓存的大小。

需要注意的是,View类的源代码可以通过SDK Manager获取(并非所有Android版本都可以获取)。


1
为了让其他人不必像我一样费力地查找代码,检查从第6193行开始。 - Ellen Spertus
@Seva 给出的链接现在无法使用,显示“410”错误。如果有人能编辑正确的链接,将不胜感激。 - AnujAroshA
Android源代码现在可以通过SDK管理器获得。谁还需要那些链接呢? - Seva Alekseyev

6
希望这能解释清楚。
public class YourCustomView extends View {

    private String mSomeProperty;

    public YourCustomView(Context context) {
        super(context);
    }

    public YourCustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public YourCustomView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public void setSomeProperty(String value) {
        mSomeProperty = value;
        setDrawingCacheEnabled(false); // clear the cache here
        invalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        // specific draw logic here

        setDrawingCacheEnabled(true); // cache
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        ...
    }

}

示例代码解释。

  1. 在setSomeProperty()方法中调用setDrawingCacheEnabled(false)来清除缓存,并通过调用invalidate()强制重新绘制。
  2. 在onDraw方法中绘制完毕后,调用setDrawingCacheEnabled(true)。
  3. 可选地,在onDraw方法中放置一个日志语句以确认每次调用setSomeProperty()方法时它只被调用一次。确保在确认后删除日志调用,因为这会成为性能问题。

3
这个功能是启用或禁用绘图缓存。当绘图缓存被启用后,下一次调用getDrawingCache()或buildDrawingCache()将把视图绘制到位图上。无论我是否添加这些行,在调用invalidate()时,我的onDraw()方法只会被调用一次。经过测试,缓存未被使用。 - 3c71
2
这是错误的。你只需要启用绘图缓存,它就会在每次调用draw时填充。但实际上这不会起作用,因为第一次调用onDraw时绘图缓存没有启用。 - dcow

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接