android.graphics.View无效(int,int,int,int)画布的一部分,但onRedraw()整个画布?

时间:2014-09-26 00:07:06

标签: android android-canvas

Android View有三个版本invalidate():一个使整个视图无效,另外两个仅使其中的一部分无效。但它只有一个onDraw(),它绘制整个画布。系统必须有一些使用暗示,我只想让部分视图无效,但我不清楚它是什么。

我有一个在onDraw()中进行自定义绘图的视图。我是否有办法找出画布的哪些部分无效,所以我只画那些?

2 个答案:

答案 0 :(得分:5)

当Android准备好向屏幕呈现更改时,它会通过创建需要重绘的所有单个矩形区域的联合(所有已经失效的区域)来实现。

当您调用视图的onDraw(Canvas画布)方法时,您可以检查Canvas是否有剪辑边界。

如果存在非空剪辑边界,您可以使用此信息来确定您将要做什么,并且不需要绘制,从而节省时间。

如果剪辑边界为空,您应该假设Android要您绘制视图的整个区域。

这样的事情:

private Rect clipBounds = new Rect();

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

    boolean isClipped = canvas.getClipBounds(clipBounds);

    // If isClipped == false, assume you have to draw everything
    // If isClipped == true, check to see if the thing you are going to draw is within clipBounds, else don't draw it
}

答案 1 :(得分:0)

  There must be some use that the system makes of the hint that I only want to 
  invalidate part of the view, but I'm unclear on what it is.

是的,确实如此。方法invalidate(int l,int t,int r,int b)有四个参数,View的父视图使用它们来计算mLocalDirtyRect,它是View类的一个字段。 mLocalDirtyRect由View类中的getHardwareLayer()方法使用,这里是它的描述:

 /**
     * <p>Returns a hardware layer that can be used to draw this view again
     * without executing its draw method.</p>
     *
     * @return A HardwareLayer ready to render, or null if an error occurred.
     */
    HardwareLayer getHardwareLayer() {

意味着Android可以刷新部分视图而无需调用View的onDraw()方法。因此,您不需要尝试自己绘制部分视图,因为当您将视图中的脏部分告知时,Android会为您执行此操作。

最后,我想您可以参考View和ViewGroup的源代码了解更多详情,这里是您可以在线阅读的链接: https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/view/View.java https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/view/ViewGroup.java