如何重绘Android Canvas

发布于 2024-11-28 08:03:13 字数 3216 浏览 2 评论 0原文

谁能帮助我如何重画画布。我尝试了很多来自互联网的示例和源代码,但它仍然无法在我的电脑上运行,例如 invalidate func、canvas.save、canvas.restore 等。我想对画布进行一些翻译和缩放,但是当我按照网上的步骤操作,什么也没显示。这是我的源代码。 (我对 Java/Android 编程还是个新手。)

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    requestWindowFeature(Window.FEATURE_NO_TITLE);
    drawMaps.j=1;
    resources = this.getResources();
    try {
        GetAttributes("path");
        } catch (XmlPullParserException e) {
          e.printStackTrace();
        } catch (IOException e) {
          e.printStackTrace();
        }
        SeekBar seekBar = (SeekBar)findViewById(R.id.seekBar1);
        panel = new Panel(this);
        setContentView(R.layout.main);
        panel.onDraw(canvas2);
        ImageView image = (ImageView) findViewById(R.id.mapImage);
            image.setImageBitmap(bufMaps);
}


class Panel extends View{
    Paint paint = new Paint();
    public Panel(Context context) {
        super(context);
        setFocusable(true);
    }


    public Bitmap quicky_XY(Bitmap bitmap,int pos_x,int pos_y){
        Bitmap bufMap = Bitmap.createBitmap(bitmap.getWidth(),
        bitmap.getHeight(), Config.ARGB_8888);
        Canvas canvas = new Canvas(bufMap);
        canvas.save();
            final Paint paint = new Paint();
            width = canvas.getWidth();//start
            height = canvas.getHeight();//end
            drawMaps.xpos = width / 30;
            drawMaps.ypos = height/ 20;

            paint.setStrokeWidth(0);
            for (int i = 0; i < 30; i++) {
                paint.setColor(Color.DKGRAY);
                canvas.drawLine(drawMaps.xpos +(drawMaps.xpos*i), 0, 
                    drawMaps.xpos +(drawMaps.xpos*i), height, paint);
            //canvas.drawLine(startX, startY, stopX, stopY, paint)
            } 
            for (int i = 0; i < 20; i++) {
                paint.setColor(Color.DKGRAY);
                canvas.drawLine(0, drawMaps.ypos+(drawMaps.ypos*i), 
                    width, drawMaps.ypos+(drawMaps.ypos*i), paint);
            }

            canvas.translate(pos_x,pos_y);
            drawMaps.addPath(canvas);
            canvas.restore();
            invalidate();
        return bufMap;
     }

    @Override
    public void onDraw(Canvas canvas) {
        canvas.save();
        bufMaps = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
        bufMaps = quicky_XY(emptyBmap,positionX,positionY);

    }

}

@Override
public boolean onTouchEvent(MotionEvent event)  
{  
 positionX = (int)event.getRawX();  
 positionY = (int)event.getRawY();  
 switch(event.getAction())  
       {  
      case MotionEvent.ACTION_DOWN: {  
            prevX = positionX;  
            prevY = positionY;  
      }  
      break;  
      case MotionEvent.ACTION_MOVE:  {  
          final int distY = Math.abs(positionY - prevY);  
          final int distX = Math.abs(positionX - prevX);    
          if (distX > mTouchSlop || distY > mTouchSlop){
                panel.getDrawingCache();
                panel.invalidate();
          }
              Log.e("LSDEBUG", "touch X, " + positionX);
      }     
      break;  
      }  
 return true;  
}

Can anyone help me on how to redraw the canvas. I tried many examples and source code from the internet, but it still didn't work on my PC like the invalidate func, canvas.save, canvas.restore, etc. I want to do some translation and scaling for the canvas, but when I follow the step on the internet it shows nothing. This is my source code. (I'm still new to Java/Android programming.)

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    requestWindowFeature(Window.FEATURE_NO_TITLE);
    drawMaps.j=1;
    resources = this.getResources();
    try {
        GetAttributes("path");
        } catch (XmlPullParserException e) {
          e.printStackTrace();
        } catch (IOException e) {
          e.printStackTrace();
        }
        SeekBar seekBar = (SeekBar)findViewById(R.id.seekBar1);
        panel = new Panel(this);
        setContentView(R.layout.main);
        panel.onDraw(canvas2);
        ImageView image = (ImageView) findViewById(R.id.mapImage);
            image.setImageBitmap(bufMaps);
}


class Panel extends View{
    Paint paint = new Paint();
    public Panel(Context context) {
        super(context);
        setFocusable(true);
    }


    public Bitmap quicky_XY(Bitmap bitmap,int pos_x,int pos_y){
        Bitmap bufMap = Bitmap.createBitmap(bitmap.getWidth(),
        bitmap.getHeight(), Config.ARGB_8888);
        Canvas canvas = new Canvas(bufMap);
        canvas.save();
            final Paint paint = new Paint();
            width = canvas.getWidth();//start
            height = canvas.getHeight();//end
            drawMaps.xpos = width / 30;
            drawMaps.ypos = height/ 20;

            paint.setStrokeWidth(0);
            for (int i = 0; i < 30; i++) {
                paint.setColor(Color.DKGRAY);
                canvas.drawLine(drawMaps.xpos +(drawMaps.xpos*i), 0, 
                    drawMaps.xpos +(drawMaps.xpos*i), height, paint);
            //canvas.drawLine(startX, startY, stopX, stopY, paint)
            } 
            for (int i = 0; i < 20; i++) {
                paint.setColor(Color.DKGRAY);
                canvas.drawLine(0, drawMaps.ypos+(drawMaps.ypos*i), 
                    width, drawMaps.ypos+(drawMaps.ypos*i), paint);
            }

            canvas.translate(pos_x,pos_y);
            drawMaps.addPath(canvas);
            canvas.restore();
            invalidate();
        return bufMap;
     }

    @Override
    public void onDraw(Canvas canvas) {
        canvas.save();
        bufMaps = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
        bufMaps = quicky_XY(emptyBmap,positionX,positionY);

    }

}

@Override
public boolean onTouchEvent(MotionEvent event)  
{  
 positionX = (int)event.getRawX();  
 positionY = (int)event.getRawY();  
 switch(event.getAction())  
       {  
      case MotionEvent.ACTION_DOWN: {  
            prevX = positionX;  
            prevY = positionY;  
      }  
      break;  
      case MotionEvent.ACTION_MOVE:  {  
          final int distY = Math.abs(positionY - prevY);  
          final int distX = Math.abs(positionX - prevX);    
          if (distX > mTouchSlop || distY > mTouchSlop){
                panel.getDrawingCache();
                panel.invalidate();
          }
              Log.e("LSDEBUG", "touch X, " + positionX);
      }     
      break;  
      }  
 return true;  
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

雪落纷纷 2024-12-05 08:03:14

您自己不调用 onDraw()。相反,您调用 invalidate() ,它将确保尽快调用 onDraw() 。

另外,如果您尝试从 onDraw() 方法外部在画布上绘图,则需要获取对画布的引用。

在 onDraw() 内部,画布没有被更改。仅保存(再次在 invalidate() 上调用或每当系统需要重绘此视图时调用):

@Override
public void onDraw(Canvas canvas) {
    canvas.save();
    bufMaps = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
    bufMaps = quicky_XY(emptyBmap,positionX,positionY);

}

从 onDraw() 外部访问画布是使用 Holder().lockCanvas() 来获取对画布的引用。绘制完成后,您可以使用unlockAndPost() 再次解锁它,仅此而已。

您还需要实现 Callback.surfaceCreated 接口来确定 Surface 何时可供使用。

查看 SurfaceHolder 的 Android 参考

这篇文章解释得很好

You do not call onDraw() yourself. Instead, you call to invalidate() and it will make sure onDraw() is called as soon as the it can.

Also, if you are trying to draw on the canvas from outside the onDraw() method, you need to get a reference to the canvas.

Inside your onDraw() the canvas is not being changed. only saved (again, called on invalidate() or whenever the system needs to redraw this View):

@Override
public void onDraw(Canvas canvas) {
    canvas.save();
    bufMaps = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
    bufMaps = quicky_XY(emptyBmap,positionX,positionY);

}

Accessing the canvas from outside the onDraw() is done using a Holder().lockCanvas() to get reference to the canvas. After drawing, you unlock it again, using unlockAndPost() and that's it.

You will also need to implement the Callback.surfaceCreated interface to find out when the Surface is available to use.

Take a look at the android reference for SurfaceHolder.

This post explains it pretty well.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文