6

いくつかの色を使用して描画できる小さなペイントアプリを作成したかったのですが、今まで正しく機能していない1つの色の変更のみをテストしました。ボタンをクリックして新しい色で描画を開始すると、以前に作成したすべての描画も色が変わります。誰かが私を助けることができますか?

public class MyTouchEventView extends View {

    private Paint paint = new Paint();
    private Path path = new Path();



    public Button btnChange;
    public LayoutParams params;

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

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


        btnChange = new Button(context);
        btnChange.setText("Chaneg color");

        params = new LayoutParams(LayoutParams.WRAP_CONTENT,
                LayoutParams.WRAP_CONTENT);
        btnChange.setLayoutParams(params);

        btnChange.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {


                paint.setColor(Color.GREEN);
            }
        });


    }

    @Override
    protected void onDraw(Canvas canvas) {

        canvas.drawPath(path, paint);

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        float pointX = event.getX();
        float pointY = event.getY();

        // Checks for the event that occurs
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            path.moveTo(pointX, pointY);

            return true;
        case MotionEvent.ACTION_MOVE:
            path.lineTo(pointX, pointY);

            break;
        default:
            return false;
        }


        postInvalidate();
        return true;
    }

}
4

3 に答える 3

4

ここでの問題は、1 つのパスしか使用しないことです。

ACTION_DOWN ごとに新しいパスを作成する必要があります。そして、これらのパスごとに、ペイントも保存する必要があります。

たとえば、両方の要素をメンバーとして持つクラスを定義できます。

public class Stroke {
    private Path _path;
    private Paint _paint;
}// add constructor(Path, Paint) and accessors

Context 内の Stroke のリスト:

List<Stroke> allStrokes = new ArrayList<Stroke>();

したがって、すべてACTION_DOWNの で、新しい Stroke を作成します (つまり、新しい Path と、選択した色の新しい Paint を作成します)。

そして、毎回ACTION_MOVE、最後に追加されたパスを取得した後lineTo、最後のポイントを取得できます。

次に、onDraw で、作成したすべての Stroke を描画します。

for (Stroke s : allStrokes) {
     canvas.drawPath(s.getPath(), s.getPaint());
}

この単純な解決策では、multiTouch 描画はできないことに注意してください。そのためには、MotionEvent ID も保存して処理する必要があります。

編集:これは、ランダムな色で塗りつぶされたストロークを作成するマルチタッチ ペイントの実際の例です。

DrawArea.java:

import android.content.Context;
import android.graphics.*;
import android.util.SparseArray;
import android.view.MotionEvent;
import android.view.View;

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

public class DrawArea extends View {

    private List<Stroke> _allStrokes; //all strokes that need to be drawn
    private SparseArray<Stroke> _activeStrokes; //use to retrieve the currently drawn strokes
    private Random _rdmColor = new Random();

    public DrawArea(Context context) {
        super(context);
        _allStrokes = new ArrayList<Stroke>();
        _activeStrokes = new SparseArray<Stroke>();
        setFocusable(true);
        setFocusableInTouchMode(true);
        setBackgroundColor(Color.WHITE);
    }

    public void onDraw(Canvas canvas) {
        if (_allStrokes != null) {
            for (Stroke stroke: _allStrokes) {
                if (stroke != null) {
                    Path path = stroke.getPath();
                    Paint painter = stroke.getPaint();
                    if ((path != null) && (painter != null)) {
                        canvas.drawPath(path, painter);
                    }
                }
            }
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        final int action = event.getActionMasked();
        final int pointerCount = event.getPointerCount();

        switch (action) {
            case MotionEvent.ACTION_DOWN: {
                pointDown((int)event.getX(), (int)event.getY(), event.getPointerId(0));
                break;
            }
            case MotionEvent.ACTION_MOVE: {
                for (int pc = 0; pc < pointerCount; pc++) {
                    pointMove((int) event.getX(pc), (int) event.getY(pc), event.getPointerId(pc));
                }
                break;
            }
            case MotionEvent.ACTION_POINTER_DOWN: {
                for (int pc = 0; pc < pointerCount; pc++) {
                    pointDown((int)event.getX(pc), (int)event.getY(pc), event.getPointerId(pc));
                }
                break;
            }
            case MotionEvent.ACTION_UP: {
                break;
            }
            case MotionEvent.ACTION_POINTER_UP: {
                break;
            }
        }
        invalidate();
        return true;
    }

    private void pointDown(int x, int y, int id) {
        //create a paint with random color
        Paint paint = new Paint();
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(10);
        paint.setColor(_rdmColor.nextInt());

        //create the Stroke
        Point pt = new Point(x, y);
        Stroke stroke = new Stroke(paint);
        stroke.addPoint(pt);
        _activeStrokes.put(id, stroke);
        _allStrokes.add(stroke);
    }

    private void pointMove(int x, int y, int id) {
        //retrieve the stroke and add new point to its path
        Stroke stroke = _activeStrokes.get(id);
        if (stroke != null) {
            Point pt = new Point(x, y);
            stroke.addPoint(pt);
        }
    }
}

ストローク.java:

import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;

public class Stroke {
    private Path _path;
    private Paint _paint;

    public Stroke (Paint paint) {
        _paint = paint;
    }

    public Path getPath() {
        return _path;
    }

    public Paint getPaint() {
        return _paint;
    }

    public void addPoint(Point pt) {
        if (_path == null) {
            _path = new Path();
            _path.moveTo(pt.x, pt.y);
        } else {
            _path.lineTo(pt.x, pt.y);
        }
    }
}

MyActivity.java:

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

public class MyActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        DrawArea da = new DrawArea(this);
        setContentView(da);
    }
}
于 2013-08-19T15:27:41.880 に答える