私は現在、学校のプロジェクトのために部分的に単純なペイントアプリを作成していますが、それは楽しいところですから、私はすべてのタッチイベントを読む今日まで私がマルチタッチを追加しようとしたときまで働いていた歴史を通して、今では1本の指で描くのはいいですが、別のものを使い始めると、Action_Downが実行されず、ランダムな線が引かれます。ここに私のコードは次のとおりです。アンドロイドは2番目のポインタにアクションを登録していません
package com.sciguy.paint;
import android.app.ProgressDialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public class DrawingView extends View {
private Paint drawPaint;
private static Canvas drawCanvas;
private List<Point> points = new CopyOnWriteArrayList<>();
private List<Point> oldPoints = new CopyOnWriteArrayList<>();
public DrawingView(Context context, AttributeSet attrs) {
super(context, attrs);
setFocusable(true);
setFocusableInTouchMode(true);
drawPaint = new Paint();
drawPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
drawPaint.setColor(CommonResources.getColor());
drawPaint.setAntiAlias(false);
drawPaint.setStrokeWidth(CommonResources.size);
drawPaint.setStyle(Paint.Style.STROKE);
drawPaint.setStrokeJoin(Paint.Join.ROUND);
drawPaint.setStrokeCap(Paint.Cap.ROUND);
if (CommonResources.oldThread == null) {
CommonResources.oldThread = DrawBitmap;
DrawBitmap.start();
} else {
CommonResources.stopThread = true;
//noinspection SynchronizeOnNonFinalField
synchronized (CommonResources.oldThread) {
CommonResources.oldThread.notify();
}
//noinspection StatementWithEmptyBody
while (CommonResources.stopThread) ;
CommonResources.oldThread = DrawBitmap;
DrawBitmap.start();
}
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (CommonResources.canvasBitmap == null) {
CommonResources.canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
}
drawCanvas = new Canvas(CommonResources.canvasBitmap);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(CommonResources.canvasBitmap, 0, 0, null);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float curX = event.getX();
float curY = event.getY();
if (CommonResources.fill) {
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
if (!CommonResources.isFillThreadRunning) {
new FloodFillThread(ProgressDialog.show(getContext(), "Flood Fill", "Filling Area..."), handler, CommonResources.canvasBitmap, new android.graphics.Point((int) curX, (int) curY), CommonResources.canvasBitmap.getPixel((int) curX, (int) curY), CommonResources.getColor()).start();
}
return true;
}
return true;
} else {
Point point;
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
point = new Point();
curX = event.getX(event.getActionIndex());
curY = event.getY(event.getActionIndex());
point.oldX = curX;
point.oldY = curY;
addOldPoint(curX, curY, event.getActionIndex());
} else {
for (int h = 0; h < event.getHistorySize(); h++) {
for (int i = 0; i < event.getPointerCount(); i++) {
curX = event.getHistoricalX(i, h);
curY = event.getHistoricalY(i, h);
point = getOldPoint(i);
point.newX = curX;
point.newY = curY;
addOldPoint(curX, curY, i);
points.add(point);
updateBitmap();
}
}
}
}
return true;
}
public static void clearScreen() {
CommonResources.canvasBitmap.eraseColor(Color.TRANSPARENT);
}
public void updateBitmap() {
synchronized (DrawBitmap) {
DrawBitmap.notify();
}
}
final Thread DrawBitmap = new Thread(new Runnable() {
@Override
public void run() {
while (!CommonResources.stopThread) {
for (Point p : points) {
drawCanvas.drawLine(p.oldX, p.oldY, p.newX, p.newY, drawPaint);
points.remove(p);
postInvalidate();
}
try {
synchronized (DrawBitmap) {
DrawBitmap.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
CommonResources.stopThread = false;
}
});
private class Point {
float newX, newY, oldX, oldY;
int id;
@Override
public String toString() {
return newX + ", " + newY + ", " + oldX + ", " + oldY;
}
}
private void addOldPoint(float x, float y, int id) {
for (Point p : oldPoints) {
if (p.id == id) {
oldPoints.remove(p);
}
}
Point p = new Point();
p.oldX = x;
p.oldY = y;
p.id = id;
oldPoints.add(p);
}
private Point getOldPoint(int id) {
for (Point p : oldPoints) {
if (p.id == id) {
return p;
}
}
return new Point();
}
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == 0) {
postInvalidate();
}
}
};
public static void updateCanvas() {
drawCanvas = new Canvas(CommonResources.canvasBitmap);
}
}
これは、ビューのためのコードであり、それはしかし、ここでほとんど自明だとにかくいくつかのことです。 CommonResourcesは、アクティビティスワップ(ビットマップ、ペイントカラーなど)の間に保存する必要のあるグローバル変数を保持するシンプルなクラスです。 ondrawメソッドで時間を節約するために、スレッドを使用してビットマップに描画します。この問題のために現在動作している塗りつぶし機能がありますが、これは他のクラスにもあります。それ以上のコードや説明が必要な場合は、私はそれを提供して喜んででしょう。
おかげで、Sciguy