我是否需要使用无效调用,如果需要,在哪里?

发布于 2024-11-27 20:04:05 字数 7565 浏览 3 评论 0原文

我有一个显示视图的活动,在视图中有一个绘制的画布,然后我有一个 ontouch 函数,它应该允许拖动/缩放画布。然而,在调试时,除了画布没有移动之外,它似乎工作正常。我认为我需要调用 invalidate,对吗?如果是这样我应该在哪里调用它?

感谢您能给我的任何帮助。

Touch.java

package org.example.touch;

import android.app.Activity;
import android.content.Context;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.os.Bundle;
import android.util.FloatMath;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;

public class Touch extends Activity implements OnTouchListener {
   private static final String TAG = "Touch";
   // These matrices will be used to move and zoom image
   Matrix matrix = new Matrix();
   Matrix savedMatrix = new Matrix();

   // We can be in one of these 3 states
   static final int NONE = 0;
   static final int DRAG = 1;
   static final int ZOOM = 2;
   int mode = NONE;

   // Remember some things for zooming
   PointF start = new PointF();
   PointF mid = new PointF();
   float oldDist = 1f;

   @Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
      GridView view = new GridView(this);
      setContentView(view);
      // ImageView view = (ImageView) findViewById(R.id.imageView);
      view.setOnTouchListener(this);

      // ...
      // Work around a Cupcake bug
      matrix.setTranslate(1f, 1f);
      view.setImageMatrix(matrix);

   }

   @Override
   public boolean onTouch(View v, MotionEvent rawEvent) {
      WrapMotionEvent event = WrapMotionEvent.wrap(rawEvent);
      // ...
      GridView view = (GridView) v;

      // Dump touch event to log
      dumpEvent(event);

      // Handle touch events here...
      switch (event.getAction() & MotionEvent.ACTION_MASK) {
      case MotionEvent.ACTION_DOWN:
         savedMatrix.set(matrix);
         start.set(event.getX(), event.getY());
         Log.d(TAG, "mode=DRAG");
         mode = DRAG;
         break;
      case MotionEvent.ACTION_POINTER_DOWN:
         oldDist = spacing(event);
         Log.d(TAG, "oldDist=" + oldDist);
         if (oldDist > 10f) {
            savedMatrix.set(matrix);
            midPoint(mid, event);
            mode = ZOOM;
            Log.d(TAG, "mode=ZOOM");
         }
         break;
      case MotionEvent.ACTION_UP:
      case MotionEvent.ACTION_POINTER_UP:
         mode = NONE;
         Log.d(TAG, "mode=NONE");
         break;
      case MotionEvent.ACTION_MOVE:
         if (mode == DRAG) {

            matrix.set(savedMatrix);
            matrix.postTranslate(event.getX() - start.x,
                  event.getY() - start.y);
         }
         else if (mode == ZOOM) {
            float newDist = spacing(event);
            Log.d(TAG, "newDist=" + newDist);
            if (newDist > 10f) {
               matrix.set(savedMatrix);
               float scale = newDist / oldDist;
               matrix.postScale(scale, scale, mid.x, mid.y);
            }
         }
         break;
      }

      view.setImageMatrix(matrix);
      return true; // indicate event was handled
   }

   /** Show an event in the LogCat view, for debugging */
   private void dumpEvent(WrapMotionEvent event) {
      // ...
      String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE",
            "POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" };
      StringBuilder sb = new StringBuilder();
      int action = event.getAction();
      int actionCode = action & MotionEvent.ACTION_MASK;
      sb.append("event ACTION_").append(names[actionCode]);
      if (actionCode == MotionEvent.ACTION_POINTER_DOWN
            || actionCode == MotionEvent.ACTION_POINTER_UP) {
         sb.append("(pid ").append(
               action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
         sb.append(")");
      }
      sb.append("[");
      for (int i = 0; i < event.getPointerCount(); i++) {
         sb.append("#").append(i);
         sb.append("(pid ").append(event.getPointerId(i));
         sb.append(")=").append((int) event.getX(i));
         sb.append(",").append((int) event.getY(i));
         if (i + 1 < event.getPointerCount())
            sb.append(";");
      }
      sb.append("]");
      Log.d(TAG, sb.toString());
   }

   /** Determine the space between the first two fingers */
   private float spacing(WrapMotionEvent event) {
      // ...
      float x = event.getX(0) - event.getX(1);
      float y = event.getY(0) - event.getY(1);
      return FloatMath.sqrt(x * x + y * y);
   }

   /** Calculate the mid point of the first two fingers */
   private void midPoint(PointF point, WrapMotionEvent event) {
      // ...
      float x = event.getX(0) + event.getX(1);
      float y = event.getY(0) + event.getY(1);
      point.set(x / 2, y / 2);
   }
}

和视图 GridView.java

package org.example.touch;

import android.app.Activity;
import android.os.Bundle;

import android.view.View;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.view.Display;
import android.graphics.Path;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.Bitmap.Config;
import android.widget.ImageView;


public class GridView extends ImageView {

    private int canvasWidth;
    private int canvasHeight;

    // private Config config;
    // private Bitmap bitmap;
    // private Canvas canvas;

    public GridView(Context context) {
        super(context);




    // config = Bitmap.Config.ARGB_8888;
    // bitmap = Bitmap.createBitmap(canvasWidth, canvasHeight, config);
    // canvas = new Canvas(bitmap);

    }


public void onDraw(Canvas canvas){
    super.onDraw(canvas);

    canvasWidth = canvas.getWidth();
    canvasHeight = canvas.getHeight();

    Paint paint = new Paint();
    paint.setStyle(Paint.Style.FILL);

    paint.setColor(Color.WHITE);
    canvas.drawPaint(paint);


    canvas.drawRect(0, 0, (float)canvasWidth, (float)canvasHeight, paint);

    int Grid_size = canvasWidth / 32;


    paint.setStyle(Style.STROKE);
        paint.setColor(Color.RED);
        for (int i = 1; i < 100; i++) {                  
                canvas.drawLine((Grid_size*i), 10, (Grid_size*i), 10+(Grid_size*10), paint);              
               }                  
        paint.setColor(Color.RED);
            for (int i = 1; i < 12; i++) {                                  
                    canvas.drawLine(10, (Grid_size*i), (Grid_size*99), (Grid_size*i), paint); 
            }
            final int FS= 500;                  //Sampling Frequency
            final int WIN=FS*20; 

            //create a test sine wave
            short[]wave = new short[WIN];
            int frequency = 1;
            int amplitude = 40;
            for (int n=0; n<WIN; n++)
                wave[n] = (short) (60.0+amplitude*Math.sin(6.282*frequency*n/FS));

            //To display the waveform

            Path path2 = new Path();
            path2.moveTo(10, 60);

            for (float x2=1; x2<WIN; x2++)
                path2.lineTo(10+(3*x2/50), wave[(int) x2]);
            Paint paint3 = new Paint();
            paint3.setColor(Color.BLACK);
            paint3.setStyle(Style.STROKE);
            canvas.drawPath(path2, paint3);
}


//public void invalidate ();

public void setImageMatrix(Matrix matrix) {
    super.setImageMatrix(matrix);

}}

I have an activity which shows a view, within the view there is a canvas which is draw, then I have an ontouch function which should allow the canvas to be dragged/zoomed. However when debugging it appears to work properly except there is no movement of the canvas. I think that I need to call invalidate, is this right? if so where should I call it?

Thanks for any help you can give me.

The Touch.java

package org.example.touch;

import android.app.Activity;
import android.content.Context;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.os.Bundle;
import android.util.FloatMath;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;

public class Touch extends Activity implements OnTouchListener {
   private static final String TAG = "Touch";
   // These matrices will be used to move and zoom image
   Matrix matrix = new Matrix();
   Matrix savedMatrix = new Matrix();

   // We can be in one of these 3 states
   static final int NONE = 0;
   static final int DRAG = 1;
   static final int ZOOM = 2;
   int mode = NONE;

   // Remember some things for zooming
   PointF start = new PointF();
   PointF mid = new PointF();
   float oldDist = 1f;

   @Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
      GridView view = new GridView(this);
      setContentView(view);
      // ImageView view = (ImageView) findViewById(R.id.imageView);
      view.setOnTouchListener(this);

      // ...
      // Work around a Cupcake bug
      matrix.setTranslate(1f, 1f);
      view.setImageMatrix(matrix);

   }

   @Override
   public boolean onTouch(View v, MotionEvent rawEvent) {
      WrapMotionEvent event = WrapMotionEvent.wrap(rawEvent);
      // ...
      GridView view = (GridView) v;

      // Dump touch event to log
      dumpEvent(event);

      // Handle touch events here...
      switch (event.getAction() & MotionEvent.ACTION_MASK) {
      case MotionEvent.ACTION_DOWN:
         savedMatrix.set(matrix);
         start.set(event.getX(), event.getY());
         Log.d(TAG, "mode=DRAG");
         mode = DRAG;
         break;
      case MotionEvent.ACTION_POINTER_DOWN:
         oldDist = spacing(event);
         Log.d(TAG, "oldDist=" + oldDist);
         if (oldDist > 10f) {
            savedMatrix.set(matrix);
            midPoint(mid, event);
            mode = ZOOM;
            Log.d(TAG, "mode=ZOOM");
         }
         break;
      case MotionEvent.ACTION_UP:
      case MotionEvent.ACTION_POINTER_UP:
         mode = NONE;
         Log.d(TAG, "mode=NONE");
         break;
      case MotionEvent.ACTION_MOVE:
         if (mode == DRAG) {

            matrix.set(savedMatrix);
            matrix.postTranslate(event.getX() - start.x,
                  event.getY() - start.y);
         }
         else if (mode == ZOOM) {
            float newDist = spacing(event);
            Log.d(TAG, "newDist=" + newDist);
            if (newDist > 10f) {
               matrix.set(savedMatrix);
               float scale = newDist / oldDist;
               matrix.postScale(scale, scale, mid.x, mid.y);
            }
         }
         break;
      }

      view.setImageMatrix(matrix);
      return true; // indicate event was handled
   }

   /** Show an event in the LogCat view, for debugging */
   private void dumpEvent(WrapMotionEvent event) {
      // ...
      String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE",
            "POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" };
      StringBuilder sb = new StringBuilder();
      int action = event.getAction();
      int actionCode = action & MotionEvent.ACTION_MASK;
      sb.append("event ACTION_").append(names[actionCode]);
      if (actionCode == MotionEvent.ACTION_POINTER_DOWN
            || actionCode == MotionEvent.ACTION_POINTER_UP) {
         sb.append("(pid ").append(
               action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
         sb.append(")");
      }
      sb.append("[");
      for (int i = 0; i < event.getPointerCount(); i++) {
         sb.append("#").append(i);
         sb.append("(pid ").append(event.getPointerId(i));
         sb.append(")=").append((int) event.getX(i));
         sb.append(",").append((int) event.getY(i));
         if (i + 1 < event.getPointerCount())
            sb.append(";");
      }
      sb.append("]");
      Log.d(TAG, sb.toString());
   }

   /** Determine the space between the first two fingers */
   private float spacing(WrapMotionEvent event) {
      // ...
      float x = event.getX(0) - event.getX(1);
      float y = event.getY(0) - event.getY(1);
      return FloatMath.sqrt(x * x + y * y);
   }

   /** Calculate the mid point of the first two fingers */
   private void midPoint(PointF point, WrapMotionEvent event) {
      // ...
      float x = event.getX(0) + event.getX(1);
      float y = event.getY(0) + event.getY(1);
      point.set(x / 2, y / 2);
   }
}

and the view, GridView.java

package org.example.touch;

import android.app.Activity;
import android.os.Bundle;

import android.view.View;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.view.Display;
import android.graphics.Path;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.Bitmap.Config;
import android.widget.ImageView;


public class GridView extends ImageView {

    private int canvasWidth;
    private int canvasHeight;

    // private Config config;
    // private Bitmap bitmap;
    // private Canvas canvas;

    public GridView(Context context) {
        super(context);




    // config = Bitmap.Config.ARGB_8888;
    // bitmap = Bitmap.createBitmap(canvasWidth, canvasHeight, config);
    // canvas = new Canvas(bitmap);

    }


public void onDraw(Canvas canvas){
    super.onDraw(canvas);

    canvasWidth = canvas.getWidth();
    canvasHeight = canvas.getHeight();

    Paint paint = new Paint();
    paint.setStyle(Paint.Style.FILL);

    paint.setColor(Color.WHITE);
    canvas.drawPaint(paint);


    canvas.drawRect(0, 0, (float)canvasWidth, (float)canvasHeight, paint);

    int Grid_size = canvasWidth / 32;


    paint.setStyle(Style.STROKE);
        paint.setColor(Color.RED);
        for (int i = 1; i < 100; i++) {                  
                canvas.drawLine((Grid_size*i), 10, (Grid_size*i), 10+(Grid_size*10), paint);              
               }                  
        paint.setColor(Color.RED);
            for (int i = 1; i < 12; i++) {                                  
                    canvas.drawLine(10, (Grid_size*i), (Grid_size*99), (Grid_size*i), paint); 
            }
            final int FS= 500;                  //Sampling Frequency
            final int WIN=FS*20; 

            //create a test sine wave
            short[]wave = new short[WIN];
            int frequency = 1;
            int amplitude = 40;
            for (int n=0; n<WIN; n++)
                wave[n] = (short) (60.0+amplitude*Math.sin(6.282*frequency*n/FS));

            //To display the waveform

            Path path2 = new Path();
            path2.moveTo(10, 60);

            for (float x2=1; x2<WIN; x2++)
                path2.lineTo(10+(3*x2/50), wave[(int) x2]);
            Paint paint3 = new Paint();
            paint3.setColor(Color.BLACK);
            paint3.setStyle(Style.STROKE);
            canvas.drawPath(path2, paint3);
}


//public void invalidate ();

public void setImageMatrix(Matrix matrix) {
    super.setImageMatrix(matrix);

}}

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

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

发布评论

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

评论(1

Oo萌小芽oO 2024-12-04 20:04:05

当您希望重绘屏幕时,请调用 invalidate 。如果你希望它不断更新,你可以在 onDraw 阶段结束时调用它,它会一遍又一遍地绘制它。

如果您只需要在缩放后重新绘制屏幕,​​请在缩放功能完成后进行

call invalidate for when you want the screen to be redrawn. If you want it to constantly update you can call it at the end of the onDraw stage and it will just draw it over and over.

If you only need the screen to be redrawn after you have zoomed then do it after the zoom function is finished

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