如何覆盖onDraw,以便我可以获取绘制的内容(作为位图)并对其进行转换?

时间:2010-05-04 07:33:59

标签: android

下面的方法有效,但不幸的是,这种方法涉及创建整个屏幕大小的位图 - 而不仅仅是绘制的区域。如果我使用它来绘制UI元素,则会为每个UI元素重新绘制 。这可以更有效地完成吗?

@Override
protected void onDraw(Canvas canvas) {
    //TODO: Reduce the burden from multiple drawing
    Bitmap bitmap=Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Config.ARGB_8888);
    Canvas offscreen=new Canvas(bitmap);
    super.onDraw(offscreen);
    //Then draw onscreen
    Paint p=new Paint();
    p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DARKEN));
    canvas.drawBitmap(bitmap, 0, 0, p);
}

3 个答案:

答案 0 :(得分:9)

以下代码将更加高效。

public class MyView extends TextView{
    private Canvas offscreen;

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

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

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

    @Override
    protected void onDraw(Canvas canvas) {
        //We want the superclass to draw directly to the offscreen canvas so that we don't get an infinitely deep recursive call
        if(canvas==offscreen){
            super.onDraw(offscreen);
        }
        else{
            //Our offscreen image uses the dimensions of the view rather than the canvas
            Bitmap bitmap=Bitmap.createBitmap(getWidth(), getHeight(), Config.ARGB_8888);
            offscreen=new Canvas(bitmap);
            super.draw(offscreen);
            //Create paint to draw effect
            Paint p=new Paint();
            p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DARKEN));
            //Draw on the canvas. Fortunately, this class uses relative coordinates so that we don't have to worry about where this View is actually positioned.
            canvas.drawBitmap(bitmap, 0, 0, p);
        }
    }
}

答案 1 :(得分:8)

您是否尝试更改您创建的位图的大小,仅等于剪辑边界而不是给定画布的整个大小?我不知道所有视图是否都是这种情况,但我发现某些视图的onDraw方法被赋予了与屏幕一样大的画布,而不管内容的实际大小。然后它会剪切画布,将其限制在左上角,然后绘制,然后将该部分转换为屏幕上的其他位置,当它实际上准备好显示整个布局时。换句话说,尽管它的画布大小与整个屏幕相同,但它实际上只使用了一小块。所以你可以尝试做的不是使用

Bitmap bitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), ...)

你可以尝试

Rect rect = canvas.getClipBounds();
int width = rect.width();
int height = rect.height();
Bitmap bitmap = Bitmap.createBitmap(width, height, ...); 

这样可以减少使用比必要更大的位图的开销。注意:我实际上没有尝试这样做,所以它可能不起作用,但值得尝试。

答案 2 :(得分:0)

我遇到了类似的东西,其中canvas.getWidth()和canvas.getHeight()返回整个屏幕的宽度和高度,而不是视图本身。

尝试使用以下代码:

Bitmap bitmap=Bitmap.createBitmap(getWidth(), getHeight(), Config.ARGB_8888);

对于我的情况,getWidth()和getHeight()返回我视图的尺寸。祝你好运!