0

以下是我的代码。我可以画线,但重做和撤消按钮不起作用。请任何人都可以帮忙。

这是我下面的活动。请检查撤消和重做方法...

public class Paint_main extends Activity implements OnTouchListener {

    static Paint p1;
    static Paint p2;
    ImageView img;
    Bitmap bm;
    Float startx;
    Float starty;
    Float endx;
    Float endy;
    Button b1;
    EditText et;
    File file; 
    File myDir;
    private static ToggleButton toggleButton;
    private Canvas mCanvas;
    private Path mPath;

    private ArrayList<Path> paths = new ArrayList<Path>();
    private ArrayList<Path> undonePaths = new ArrayList<Path>();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Button btn_undo = (Button) findViewById(R.id.undoButton);

        btn_undo.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) { onClickUndo(); }
        });

        Button btn_redo = (Button) findViewById(R.id.redoButton);

        btn_redo.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) { onClickRedo(); }
        });

        bm = Bitmap.createBitmap(getWindowManager().getDefaultDisplay().getWidth(),
                                 getWindowManager().getDefaultDisplay().getHeight(),
                                 Bitmap.Config.ARGB_8888);

        img = (ImageView) findViewById(R.id.imageView1);    
        img.setImageBitmap(bm);

        p1 = new Paint();
        p1.setAntiAlias(true);
        p1.setDither(true);
        p1.setStyle(Paint.Style.STROKE);
        p1.setStrokeJoin(Paint.Join.ROUND);
        p1.setStrokeCap(Paint.Cap.ROUND);
        p1.setColor(Color.GREEN);
        p1.setStrokeWidth(6);
        mCanvas = new Canvas(bm);
        mPath = new Path();
        // paths.add(mPath); 
        img.setOnTouchListener(this);
    }

    private float mX, mY;
    private static final float TOUCH_TOLERANCE = 4;

    private void touch_start(float x, float y) {
        mPath.reset();
        mPath.moveTo(x, y);
        mX = x;
        mY = y;
    }

    private void touch_move(float x, float y) {
        float dx = Math.abs(x - mX);
        float dy = Math.abs(y - mY);

        if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
            mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
            mX = x;
            mY = y;
        }
    }

    private void touch_up() {
        mPath.lineTo(mX, mY);
        // commit the path to our offscreen
        mCanvas.drawPath(mPath, p1);
        // kill this so we don't double draw            
        // mPath = new Path();
        // paths.add(mPath);
        paths.add(mPath);
        mPath = new Path();
    }

    public void onClickUndo () { 
        if (paths.size() > 0) { 
            undonePaths.add(paths.remove(paths.size()-1));
            img.invalidate();
            onDraw(mCanvas);
        }
    }

    public void onClickRedo (){
        if (undonePaths.size() > 0) { 
            paths.add(undonePaths.remove(undonePaths.size()-1)); 
            img.invalidate();
            onDraw(mCanvas);
        } 
    }


    public boolean onTouch(View arg0, MotionEvent event) {
        float x = event.getX();
        float y = event.getY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                touch_start(x, y);
                img.invalidate();
                onDraw(mCanvas);
                break;
            case MotionEvent.ACTION_MOVE:
                touch_move(x, y);
                img.invalidate();
                onDraw(mCanvas);
                break;
            case MotionEvent.ACTION_UP:
                touch_up();
                img.invalidate();
                onDraw(mCanvas);
                break;
        }
        return true;
    }

    protected void onDraw(Canvas canvas) {
        //mPath = new Path();
        //canvas.drawPath(mPath, mPaint);

        for (Path p : paths) { canvas.drawPath(p, p1); }
        canvas.drawPath(mPath, p1);
    }
}

可能是我错误地调用了上面的 onDraw 方法。

4

1 回答 1

0

我得到它。问题是:img.setOnTouchListener(this);这个get事件,处理它并返回true,这意味着这个事件被处理了。

您有 3 个选项:

1)设置onTouchListener为父视图并手动将触摸事件发送给孩子 2)您可以确定用户是否触摸图像return true,否则返回 false 3)编写自己的类和覆盖onTouchEvent(..)方法

我推荐3个选项。我为你重写:

package com.example.paint_main;

import java.io.File;
import java.util.ArrayList;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ToggleButton;

public class Paint_main extends Activity  {

    MyImageView img;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_paint_main);

        img = (MyImageView) findViewById(R.id.imageView1);
        img.init(getWindowManager().getDefaultDisplay().getWidth(), getWindowManager().getDefaultDisplay().getHeight());

        Button btn_undo = (Button) findViewById(R.id.undoButton);

        btn_undo.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) { img.onClickUndo(); }
        });

        Button btn_redo = (Button) findViewById(R.id.redoButton);

        btn_redo.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) { img.onClickRedo(); }
        });
    }

    static class MyImageView extends ImageView {

        static Paint p1;
        static Paint p2;
        Bitmap bm = null;
        Float startx;
        Float starty;
        Float endx;
        Float endy;
        Button b1;
        EditText et;
        File file; 
        File myDir;
        private static ToggleButton toggleButton;
        private Canvas mCanvas;
        private Path mPath;

        private ArrayList<Path> paths = new ArrayList<Path>();
        private ArrayList<Path> undonePaths = new ArrayList<Path>();

        static {
            p1 = new Paint();
            p1.setAntiAlias(true);
            p1.setDither(true);
            p1.setStyle(Paint.Style.STROKE);
            p1.setStrokeJoin(Paint.Join.ROUND);
            p1.setStrokeCap(Paint.Cap.ROUND);
            p1.setColor(Color.GREEN);
            p1.setStrokeWidth(6);
        }

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

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

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

        public void init(int width, int height) {
            bm = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
            mCanvas = new Canvas(bm);
            mPath = new Path();
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            float x = event.getX();
            float y = event.getY();

            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    touch_start(x, y);
                    this.invalidate();
                    onDraw(mCanvas);
                    break;
                case MotionEvent.ACTION_MOVE:
                    touch_move(x, y);
                    this.invalidate();
                    onDraw(mCanvas);
                    break;
                case MotionEvent.ACTION_UP:
                    touch_up();
                    this.invalidate();
                    onDraw(mCanvas);
                    break;
            }
            return true;
        }

        private float mX, mY;
        private static final float TOUCH_TOLERANCE = 4;

        private void touch_start(float x, float y) {
            mPath.reset();
            mPath.moveTo(x, y);
            mX = x;
            mY = y;
        }

        private void touch_move(float x, float y) {
            float dx = Math.abs(x - mX);
            float dy = Math.abs(y - mY);

            if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
                mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
                mX = x;
                mY = y;
            }
        }

        private void touch_up() {
            mPath.lineTo(mX, mY);
            // commit the path to our offscreen
            mCanvas.drawPath(mPath, p1);
            // kill this so we don't double draw            
            // mPath = new Path();
            // paths.add(mPath);
            paths.add(mPath);
            mPath = new Path();
        }

        public void onClickUndo () { 
            if (paths.size() > 0) { 
                undonePaths.add(paths.remove(paths.size()-1));
                invalidate();
                onDraw(mCanvas);
            }
        }

        public void onClickRedo (){
            if (undonePaths.size() > 0) { 
                paths.add(undonePaths.remove(undonePaths.size()-1)); 
                invalidate();
                onDraw(mCanvas);
            } 
        }

        protected void onDraw(Canvas canvas) {
            //mPath = new Path();
            //canvas.drawPath(mPath, mPaint);

            if (bm == null)
                return;

            for (Path p : paths) { 
                canvas.drawPath(p, p1); }
                canvas.drawPath(mPath, p1);
        }
    }
} 

不要忘记将您的课程添加到布局中:

<view class="com.example.paint_main.Paint_main$MyImageView"
    android:id="@+id/imageView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_above="@+id/redoButton"
    android:layout_alignParentLeft="true"
    android:layout_alignParentRight="true"
    android:layout_alignParentTop="true" />

此外,您应该使用 View 而不是 ImageView,因为您不使用任何特定的 ImageView 函数。我用 ImageView 重写,以便更容易理解我在第三个选项中的意思。

于 2013-02-06T13:43:37.867 回答