如何禁用invalidate()方法?

3
起初我的程序长这样: enter image description here 但当我移动图片时,程序变成了这个样子: enter image description here 红色图形是在onDraw方法中随机生成的。所以我想要能够拖动图片并且有一个静态的背景,在移动图片时不会使其失效。
这是我的代码: 自定义View: package com.graph.base;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;
import java.util.Random;

public class CustomView extends View
{
Random random=new Random();
public CustomView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

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

public CustomView(Context context) {
    super(context);
}
public void onDraw (Canvas canvas)
{
    super.onDraw(canvas);
    Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setStyle(Paint.Style.FILL);
    paint.setColor(Color.WHITE);
    canvas.drawPaint(paint);
    Path path=new Path();
    path.moveTo(10, 10);
    for (float i=0.5f; i<=140; i+=10)
    {
        path.quadTo(10+i*5, 10+random.nextInt(500), 10+(i+10)*5,     10+random.nextInt(500));
    }
    paint.setDither(true);
    paint.setColor(Color.RED);
    paint.setStyle(Paint.Style.STROKE);    
    paint.setStrokeJoin(Paint.Join.ROUND);
    paint.setStrokeCap(Paint.Cap.ROUND);
    paint.setStrokeWidth(2);
    canvas.drawPath(path, paint);
}

}

MainActivity

package com.graph.base;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;

public class MainActivity extends Activity {
FrameLayout frame;
ImageView image;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    frame=(FrameLayout)findViewById(R.id.frameLayout1);
    image=(ImageView)findViewById(R.id.imageView1);
    image.setOnTouchListener(new View.OnTouchListener() {

        public boolean onTouch(View v, MotionEvent event) {
            Log.e("TAG", "Touch happend");
            switch (event.getAction())
            {
            case MotionEvent.ACTION_MOVE:
            {
                image.setPadding((int)event.getX(),     (int)event.getY(), 0, 0);
                break;
            }

            }

            return true;
        }
    });
}

public void invalidateButton_Click (View v)
{
    frame.invalidate();
}
}
2个回答

0
实际上,你不应该“禁用invalidate”,而是真正调用“invalidate”...

case MotionEvent.ACTION_MOVE:
        {
            image.setPadding((int)event.getX(),     (int)event.getY(), 0, 0);
            // here call frame.invalidate(Rect dirty), with dirty set to where the image was previously
            break;
        }

请注意,如果您的自定义视图绘制“随机”,那么您可以获取缓存版本的位图并从中绘制(blit复制)。

0
你正在画随机线条到你的画布上。每次屏幕无效时都会调用此代码。如果你想保持绘图不变,那么将一个位图设置到画布中并在位图上绘制。在你的onDraw()方法中,你将把位图绘制到画布上。
// Outside of onDraw()
Bitmap bmDest = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
Canvas mycanvas = new Canvas(bmDest);
// Do your drawing on the canvas outside of the onDraw() method

在onDraw()中,你只需要这样做:
canvas.drawBitmap(bmDest, x, y, null);

你的代码看起来还不错,除了drawBitmap()方法。这两个数字是左上角的x/y坐标,而不是宽度/高度。由于你没有向我展示错误信息,所以我无法发表评论。你真的需要正确地设计绘图逻辑,使其按照你的期望工作。 - BitBank
也许我会发布我的想法?画布 - 一张纸,位图 - 皮肤,在上面我们做和在纸上一样的事情,但然后我们可以把它放到银行里并随处使用?我们通过构造函数canvas=new Canvas(bitmap)将皮肤放在纸上,然后我们像canvas.drawPath一样在纸上绘画,但此时我们的位图也在绘制?我们有相同的画布,但是以另一种格式呈现?不知道怎么解释,因为我的英语很差。 - m9_psy
Android的GUI与许多图形系统类似,当需要更改时,会有无效显示的概念。如果您当前的视图具有滚动功能,则滚动显示将使其无效,并导致调用onDraw()方法。然后,您的代码负责重新绘制显示。如果您在每个onDraw()调用中随机绘制,那么在滚动视图时它看起来会很杂乱。您需要以某种形式保留您的图形信息,位图是保存绘图的好方法。可以在任何时候绘制位图,然后在新位置重新绘制。 - BitBank
是的,我明白,onDraw()在我做某些事情时被调用,但我不明白如何从屏幕上保存我的数据。逻辑不是问题,很简单清晰,问题出在代码上。 - m9_psy
似乎逻辑仍然是问题所在。你的纸张类比有些混淆。实际上很简单。位图对象可以在内存中保存图像。它将保留您的绘图指令。当前视图可以随时要求进行绘制。当onDraw()方法被调用时,您只需将位图绘制到画布上即可。 - BitBank
显示剩余3条评论

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