【问题标题】:Scrollview Optimizations滚动视图优化
【发布时间】:2011-07-31 04:47:21
【问题描述】:

我有一个包含自定义视图的滚动视图。自定义视图大于屏幕区域并且可以正常绘制。

然而,滚动视图在滚动时往往会不停地调用 onDraw(),我似乎无法使其平滑。

我使用 ScrollView.getDrawingRect() 来计算屏幕的可见部分并只绘制到该部分,但它仍然返回整个视口(因此它被优化为不绘制屏幕外区域),而不是最后一个位置之间的增量和当前的。理想情况下,我只想绘制增量,而不是整个可见窗口。

如果有人可以向我指出有关如何使用绘图缓存的更多信息,并且如果这有助于优化滚动,我很乐意实现它,或者任何其他可能的解决方案,将不胜感激。

【问题讨论】:

    标签: android optimization view


    【解决方案1】:

    滚动内容时,需要重新绘制整个视口,因为所有内容都已移动。我认为不需要做任何事情来优化ScrollView - 如果滚动很慢,那么它是您自定义视图的绘制方法太慢了。

    尽量避免在绘图方法中创建对象,这通常是导致绘图性能不佳的主要原因。

    编辑:滚动视图也可以快速向上或向下移动仍在屏幕上绘制的旧内容,然后请求仅重绘屏幕的“新”部分。 (仅适用于不透明视图)。

    【讨论】:

    • 有更好的解决方案,我可以通过将视图绘制到位图来实现自己的缓存,然后在 onDraw 上绘制该位图,而不是重新计算我的视图。 android视图缓存应该能够做类似的事情,并且文档提示它,但我从未见过清楚解释视图缓存的东西。
    • 你看过groups.google.com/group/android-developers/browse_thread/thread/…。但我同意,绘图缓存的话题没有得到很好的讨论。
    • 现在我刚刚实现了位图路由。在我的 onDraw 中,我查看是否有缓存位图,如果确实存在,将其创建为与视图相同的大小,而不是使用指向位图的画布调用我的旧 onDraw。与常规 onDraw 相比,它只绘制位图。这是一个内存/性能的权衡,但我同意这里,因为这些视图不应该变得很大。如果它无法分配缓存,我可以退回到直接绘制到视图。
    【解决方案2】:

    我遇到了同样的问题。我通过使用函数setDrawingCacheEnabled(true) 解决了它。通过启用此设置,您的画布视图将被缓存为位图,因此您不必每次调用 onDraw() 时都调用画布的绘制方法。

    在您的自定义视图的构造函数中,您将需要这样的东西:

    public CustomView(Context context) {
        setDrawingCacheEnabled(true);
        drawnFlag = false;
    }
    

    在您的 onDraw 方法中,您将需要这样的内容:

    public void onDraw(Canvas canvas) {
        if (! drawnFlag) {
            canvas.drawPath(...);
            canvas.drawPath(...);
            drawnFlag = true;
        }
    }
    

    现在,在这个自定义视图上滚动应该很流畅,因为我们只调用了一次绘图方法。

    【讨论】:

    • 我不知道为什么没有人支持您的回答。有用! @安德烈
    【解决方案3】:

    Afaik ScrollView 在您的视图进入 onDraw 的画布上设置了正确的剪辑矩形,因此您只需要绘制该矩形内的内容。 您还可以根据剪辑矩形的大小实现缓存位图。

    【讨论】:

      猜你喜欢
      • 2021-10-16
      • 1970-01-01
      • 2012-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-22
      • 1970-01-01
      相关资源
      最近更新 更多