java - Android - 如何从另一个类调用 invalidate() 方法?

标签 java android static

我需要从我的 MainActivity 类中调用 invalidate() 方法。我可以从我的 CanvasView 类中调用它,但是从 MainActivity 中,它会给我一个错误。说无效是非静态方法。我该如何克服这个问题?我搜索并尝试了一些解决方案,但没有成功。

我想从屏幕上删除绘制的项目,但是当我从菜单列表中选择撤消时,它不会更新屏幕。只有当我触摸屏幕时,它才会撤消元素。

我的 CanvasView 类

package com.example.HW3;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
/**
 * Android Kimp.
 * @author Martin
 *
 */
public class CanvasView extends View {
/**
 * Rectangles.
 */
    private Rect rectangle = new Rect();
/**
 * These help calculating rectangle coordinates.
 */
    private float d1 = 0, d2 = 0;
/**
 * Canvas.
 */
    private Canvas canvas = new Canvas();
/**
 *  Paint to draw shapes.
 */
    private Paint paint = new Paint();
    /**
     *  Paint to draw shapes.
     */
    private Paint paint2 = new Paint();
    /**
     *  Paint to draw shapes.
     */
    private Paint paint3 = new Paint();
    /**
     *  Paint to draw shapes.
     */
    private Paint paint4 = new Paint();
/**
 * Path.
 */
    private Path path = new Path();
/**
 * Point.
 */
    private Point point = new Point();
/**
 * List for lines.
 */
    private static List<Path> lines = new ArrayList<Path>();
    private static List<Path> lines2 = new ArrayList<Path>();
/**
 * List for points.
 */
    private static List<Point> points = new ArrayList<Point>();
    private static List<Point> points2 = new ArrayList<Point>();
/**
 * List for rectangles.
 */
    private static List<Rect> rectangles = new ArrayList<Rect>();
    private static List<Rect> rectangles2 = new ArrayList<Rect>();

    private static List<Integer> elements = new ArrayList<Integer>();
    private static List<Integer> elements2 = new ArrayList<Integer>();
/**
 * Touch coordinates.
 */
    private float x, startX, endX;
/**
 * Touch coordinates.
 */
    private float y, startY, endY;
/**
 * This checks whether user draws a line or a point.
 */

    private int whichShape;

    private boolean touchStarted = false;
/**
 * Enum to hold the value of DrawMode, whether user wants to draw lines or rectangles.
 *
 */
    public enum undoRedo {
        DoUndoRedo, DoNothing
    };

    public static undoRedo currentState = undoRedo.DoNothing;

    public enum DrawMode {
        /**
         * DrawMode possibilities.
         */
        FreeDrawMode, RectDrawMode, SelectAndDrag
    };
/**
 * Sets current DrawMode, when application starts.
 */
    public static DrawMode currentDrawMode = DrawMode.FreeDrawMode;
/**
 * Sets DrawMode.
 * @param newDrawMode
 */
    final Handler handler = new Handler();
    /**
     * Runnable interface to detect long press.
     */
    Runnable mLongPressed = new Runnable() {
        public void run() {
            for (int i = 0; i < getRectangles().size(); i++) {
            Log.i("", "Long press!");
            Rect a = getRectangles().get(i);
            System.out.println(a + " " + i);
            double x = getRectangles().get(i).left;
            System.out.println(a + " " + x);
            currentDrawMode = DrawMode.SelectAndDrag;
        }
        }
    };
/**
 * CanvasView.
 * @param context
 * @param attrs
 */



    public CanvasView(Context context, AttributeSet attrs) {
        super(context, attrs);

        paint.setAntiAlias(true);
        paint.setStrokeWidth(3);
        paint.setColor(Color.BLACK);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeJoin(Paint.Join.ROUND);

        paint2.setAntiAlias(true);
        paint2.setStrokeWidth(3);
        paint2.setColor(Color.RED);
        paint2.setStyle(Paint.Style.STROKE);
        paint2.setStrokeJoin(Paint.Join.ROUND);


        paint3.setAntiAlias(true);
        paint3.setColor(Color.BLACK);
        paint3.setStrokeWidth(3);
        paint3.setStyle(Paint.Style.STROKE);
        paint3.setStrokeJoin(Paint.Join.ROUND);

        paint4.setAntiAlias(true);
        paint4.setColor(Color.BLACK);
        paint4.setStrokeWidth(3);
        paint4.setStyle(Paint.Style.STROKE);
        paint4.setShadowLayer(10,5,5,Color.BLACK);
        paint4.setStrokeJoin(Paint.Join.ROUND);
    }

    @Override
    protected void onDraw(Canvas canvas) {

        for (Rect r : getRectangles()) {
            canvas.drawRect(r, paint);
        }
        canvas.drawRect(rectangle, paint3);

        for (Path p : getLines()) {
            canvas.drawPath(p, paint);
        }
        canvas.drawPath(path, paint2);

        for (Point point : getPoints()) {
            canvas.drawCircle(point.x, point.y, 1, paint);
    }
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        x = event.getX();
        y = event.getY();

        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            handler.postDelayed(mLongPressed, 500);
        }
        if ((event.getAction() == MotionEvent.ACTION_MOVE)
            || (event.getAction() == MotionEvent.ACTION_UP)) {
            handler.removeCallbacks(mLongPressed);
        }
        if (currentDrawMode == DrawMode.FreeDrawMode) {
            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // Set new starting point
                paint2.setColor(Color.RED);
                path = new Path();
                path.moveTo(x, y);
                touchStarted = true;
                break;

            case MotionEvent.ACTION_MOVE:
                touchStarted = false;
                path.lineTo(x, y);

                break;
            case MotionEvent.ACTION_UP:
                if (touchStarted) {
                    point = new Point();
                    point.x = (int) x;
                    point.y = (int) y;
                    paint2.setColor(Color.BLACK);
                    whichShape = 1;
                    getElements().add(whichShape);
                    getPoints().add(point);
                    getElements2().clear();
                    touchStarted = false;
                    System.out.println("here");
                } else {
                    System.out.println("there");
                    paint2.setColor(Color.BLACK);
                    whichShape = 2;
                    getElements().add(whichShape);
                    getLines().add(path);
                    getElements2().clear();
                }
                break;
            default:
                return false;
            }
        } else if (currentDrawMode == DrawMode.RectDrawMode) {

            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // Set a new starting point
                rectangle = new Rect();
                paint3.setColor(Color.RED);
                startX = event.getX();
                startY = event.getY();
                System.out.println("down");

                break;
            case MotionEvent.ACTION_MOVE:
                endX = event.getX();
                endY = event.getY();
                System.out.println("move");
                System.out.println(startX + " " + endX + " " + startY + " " + endY);

                if (startX >= endX && startY >= endY) {

                    rectangle.set((int) endX, (int) endY, (int) startX,
                            (int) startY);
                    canvas.drawRect(rectangle, paint2);
                } else if (startX >= endX && startY <= endY) {
                    d1 = startX + (endX - startX);

                    d2 = startY + (endY - startY);

                    rectangle.set((int) d1, (int) startY, (int) startX,
                            (int) d2);
                    canvas.drawRect(rectangle, paint3);
                } else if (startX <= endX && startY >= endY) {

                    d1 = startY + (endY - startY);
                    d2 = startX + (endX - startX);

                    rectangle.set((int) startX, (int) d1, (int) d2,
                            (int) startY);
                    canvas.drawRect(rectangle, paint3);
                    System.out.println("olen siin");
                } else {

                    rectangle.set((int) startX, (int) startY, (int) endX,
                            (int) endY);
                    canvas.drawRect(rectangle, paint3);
                }
                break;
            case MotionEvent.ACTION_UP:
                System.out.println("up");
                paint3.setColor(Color.BLACK);
                whichShape = 3;
                getElements().add(whichShape);
                getRectangles().add(rectangle);
                getElements2().clear();
                break;
            default:    
                return false;
            }
        } else if (currentDrawMode == DrawMode.SelectAndDrag) {
            switch (event.getAction()) {
            case MotionEvent.ACTION_MOVE:


                break;
            case MotionEvent.ACTION_UP:

                break;
            default:
                return false;
            }
        }
        // Makes our view repaint and call onDraw
        invalidate();
        return true;
    }

    public static List<Integer> getElements() {
        return elements;
    }

    public static void setElements(List<Integer> elements) {
        CanvasView.elements = elements;
    }

    public static List<Point> getPoints() {
        return points;
    }

    public static void setPoints(List<Point> points) {
        CanvasView.points = points;
    }

    public static List<Path> getLines() {
        return lines;
    }

    public static void setLines(List<Path> lines) {
        CanvasView.lines = lines;
    }

    public static List<Rect> getRectangles() {
        return rectangles;
    }

    public static void setRectangles(List<Rect> rectangles) {
        CanvasView.rectangles = rectangles;
    }

    public static List<Point> getPoints2() {
        return points2;
    }

    public static void setPoints2(List<Point> points2) {
        CanvasView.points2 = points2;
    }

    public static List<Integer> getElements2() {
        return elements2;
    }

    public static void setElements2(List<Integer> elements2) {
        CanvasView.elements2 = elements2;
    }

    public static List<Path> getLines2() {
        return lines2;
    }

    public static void setLines2(List<Path> lines2) {
        CanvasView.lines2 = lines2;
    }

    public static List<Rect> getRectangles2() {
        return rectangles2;
    }

    public static void setRectangles2(List<Rect> rectangles2) {
        CanvasView.rectangles2 = rectangles2;
    }
}

我的 MainActivity 类

package com.example.HW3;

import com.example.HW3.CanvasView.undoRedo;
import com.example.androiddrawing.R;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Window;
import android.view.WindowManager;
/**
 * Android application.
 * @author Martin
 *
 */
public class MainActivity extends Activity {


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

        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
                                WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.activity_main);


    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.default_drawing) {
            CanvasView.currentDrawMode = CanvasView.DrawMode.FreeDrawMode;
            return true;
        } else if (id == R.id.draw_rectangle) {
            CanvasView.currentDrawMode = CanvasView.DrawMode.RectDrawMode;
            return true;
        } else if (id == R.id.undo) {
            int listSize = CanvasView.getElements().size();
              System.out.println(CanvasView.getElements().size());
              if (CanvasView.getElements().size() == 0) {
                return true;  
              } else if (CanvasView.getElements().get(listSize - 1) == 1) {

                  // I WANT TO CALL INVALIDATE() FROM HERE CanvasView.getPoints2().add(CanvasView.getPoints().get(CanvasView.getPoints().size() - 1));
                  CanvasView.getElements2().add(1);
                  CanvasView.getPoints().remove(CanvasView.getPoints().size() - 1);
                  CanvasView.getElements().remove(CanvasView.getElements().size() - 1);
                  CanvasView.currentState = CanvasView.undoRedo.DoUndoRedo;
                  return true;
              } else if (CanvasView.getElements().get(listSize - 1) == 2) {

                  CanvasView.getLines2().add(CanvasView.getLines().get(CanvasView.getLines().size() - 1));
                  CanvasView.getElements2().add(2);
                  CanvasView.getLines().remove(CanvasView.getLines().size() - 1);
                  CanvasView.getElements().remove(CanvasView.getElements().size() - 1);
                  CanvasView.currentState = CanvasView.undoRedo.DoUndoRedo;
                  return true;
              } else if (CanvasView.getElements().get(listSize - 1) == 3) {

                  CanvasView.getRectangles2().add(CanvasView.getRectangles2().get(CanvasView.getRectangles2().size() - 1));
                  CanvasView.getElements2().add(3);
                  CanvasView.getRectangles().remove(CanvasView.getRectangles().size() - 1);
                  CanvasView.getElements().remove(CanvasView.getElements().size() - 1);
                  CanvasView.currentState = CanvasView.undoRedo.DoUndoRedo;
                  return true;
              }
            return true;
        } else if (id == R.id.redo) {
            int listSize2 = CanvasView.getElements2().size();
              System.out.println(CanvasView.getElements2().size());
              if (CanvasView.getElements2().size() == 0) {
                return true;  
              } else if (CanvasView.getElements2().get(listSize2 - 1) == 1) {

                  CanvasView.getPoints().add(CanvasView.getPoints2().get(CanvasView.getPoints2().size() - 1));
                  CanvasView.getPoints2().remove(CanvasView.getPoints2().size() - 1);
                  CanvasView.getElements2().remove(CanvasView.getElements2().size() - 1);
                  CanvasView.getElements().add(1);
                  CanvasView.currentState = CanvasView.undoRedo.DoUndoRedo;
                  return true;
              } else if (CanvasView.getElements2().get(listSize2 - 1) == 2) {

                  CanvasView.getLines().add(CanvasView.getLines2().get(CanvasView.getLines2().size() - 1));
                  CanvasView.getLines2().remove(CanvasView.getLines2().size() - 1);
                  CanvasView.getElements2().remove(CanvasView.getElements().size() - 1);
                  CanvasView.getElements().add(2);
                  CanvasView.currentState = CanvasView.undoRedo.DoUndoRedo;
                  return true;
              } else if (CanvasView.getElements2().get(listSize2 - 1) == 3){

                  CanvasView.getRectangles().add(CanvasView.getRectangles2().get(CanvasView.getRectangles2().size() - 1));
                  CanvasView.getRectangles2().remove(CanvasView.getRectangles2().size() - 1);
                  CanvasView.getElements2().remove(CanvasView.getElements2().size() - 1);
                  CanvasView.getElements().add(3);
                  CanvasView.currentState = CanvasView.undoRedo.DoUndoRedo;
                  return true;
              }
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
      @Override
      public void onBackPressed() {
          AlertDialog.Builder builder = new AlertDialog.Builder(this);
          builder.setTitle("Exit");
          builder.setMessage("Are You Sure?");

          builder.setNegativeButton("Yes", new DialogInterface.OnClickListener() {
              public void onClick(DialogInterface dialog, int which) {
                      dialog.dismiss();
                      System.exit(0);
              }
          });   

          builder.setPositiveButton("No", new DialogInterface.OnClickListener() {
              @Override
              public void onClick(DialogInterface dialog, int which) {
                  dialog.dismiss();
              }
          });

          AlertDialog alert = builder.create();
          alert.show();

      }
}

Activiti_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/rect"
    tools:context="com.example.HW3.MainActivity" >

    <com.example.HW3.CanvasView
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

最佳答案

我假设您已经在 res/layout/activity_main.xml 中定义了 CanvasView(并为其分配了一个 id,例如“custom_view”) 您不应静态调用 Canvas 方法(直接从类本身调用),而应从 Android 创建的实际实例调用。您可以通过将 MainActivity 更改为如下内容来获取它:

public class MainActivity extends Activity {
private CanvasView canvasView;

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

    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
                            WindowManager.LayoutParams.FLAG_FULLSCREEN);

    setContentView(R.layout.activity_main);

    canvasView = findViewById(R.id.custom_view)
}

...

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    ...
    canvasView.invalidate();
    ...
}

关于java - Android - 如何从另一个类调用 invalidate() 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27011828/

相关文章:

java - 为什么在这段代码中,信号量是向上计数而不是向下计数?

android - 在 Android Studio(在 Mac 上)中启动 AVD(Android 虚拟设备)时遇到问题

android - Drawable 优于 android 中内存位图的优势

ios - 静态计算变量被多次实例化

c# - 静态是否意味着没有状态

java - 有没有办法在数组列表中定义索引的值?

java - 如何通过双击表格行从一个选项卡移动到另一个选项卡

c++ - 为什么本地类中不允许使用静态数据成员?

java - 是什么原因导致 OpenSplice 中出现此 Java 错误?

android - 手动设置Firebase Firestore缓存