ドットのグリッドを描画するアプリがあります(たとえば3x3)。ユーザーは、そのグリッド上に何かを描画するように求められます。ユーザーの指がグリッド内のドットの1つに触れると、このドットは色付けされます。さらに、タッチした2つのドットの間に線が引かれます。
問題--event.getAction()は、多くの場合、MotionEvent.ACTION_MOVEを見逃します。どういう意味ですか?-さて、ユーザーが3つの点を結ぶ直線を描いたとしましょう。多くの場合、最初のドットは色付けされ、3番目(最後)のドットは色付けされますが、2番目(中央)のドットは色付けされません。
そこで、何をしているのかを記録したところ、画面上の指の位置の変化に「気付かない」else if(event.getAction() == MotionEvent.ACTION_MOVE)
ことがよくあることがわかりました。event.getAction()
描きたい想像上の道に沿って指をゆっくりと通過させるとevent.getAction()
、指の動きに気づきやすくなります。
いくつかのテストの後、画面に線を引くにつれて、ゲームがますます遅くなったり遅くなったりすることにも気づきました。そのアプリは非常に多くのデータ(イベントデータ?)を収集しているため、タイムリーに処理できていないようです(ログを取得します:I / Choreographer:45フレームスキップしました!アプリケーションが処理しすぎている可能性がありますメインスレッド上)。これは、ある種の特大のキャッシュの問題でしょうか?ユーザーのアクションが完了したことがわかったら、どうすればその「キャッシュ」をクリーンアップできますか?
システムが指の動きを十分に速く追跡できないような場合の経験はありますか?
============さらなる実験==========================
@Jimpanzeeが書いたものを読んだ後、ドキュメントをさらに掘り下げました。getHistoricalX(int、int)とgetHistoricalY(int、int)の使用について読みました。Androidはモーションイベントをバッチ処理しているように見えるため、getXとgetYはそのバッチの最後のイベントのみを配信する可能性があります。画面上で速い動きがある場合、これは問題になる可能性があります。そこで、getXとgetYに加えて、getHistoricalXとgetHistoricalYを使用するようになりました。これはいくつかの奇妙な理由で問題を解決しませんでした:私はまだ触れられているが色付けされていないドットを取得します。
以下に例を示します。
私はArrayListを使用しています>各ArrayListは、ドットがタッチされた順序でドットで構成されたパスを定義します。ArrayListはすべてのパスを保持します
- グリッドには、X軸とY軸のそれぞれで0、100、200、300、400の番号が付けられています
- 気絶した最初のドットは[100、100]でした。指が完全に下がって、4つのドットがペイントされ、最後のドットは[100、400]でした。
- 2番目の線も上から下に描かれていますが、上から3番目のドット[200、300]が欠落していることがわかります。
それを説明できなかったので、タッチイベントをログに記録しました。
- moveHは、アクションMOVE+履歴データを意味します
- moveCは、アクションMOVE+現在のデータを意味します
- タッチした点がグリッド上の点に近づいたとき[点を追加]が記録されます
- 時々、パスの配列全体が印刷されます
ログを見ると、ポイント[200、200]を追加した後、Y値が奇妙になっていることがわかります。Y値は212.53839(最後に表示された履歴ポイント)から412.45544にジャンプし、次のドットがアレイに追加されました。これが、ドット[200、300]が省略され、描画されなかった理由を説明しています。
383: Action moveH x: 198.75 y: 284.8833
383: Action moveH x: 199.6875 y: 305.07257
387: Action moveH x: 204.84375 y: 326.94427
387: Action moveH x: 196.875 y: 212.53839
387: Action moveH [add point] x: 200 y: 200
387: [[Point(100, 100), Point(100, 200), Point(100, 300), Point(100, 400)], [Point(200, 100), Point(200, 200)]]
504: Action moveE x: 210.0 y: 412.45544
504: Action moveH x: 205.78125 y: 345.4511
504: Action moveH x: 207.1875 y: 362.2755
504: Action moveH x: 207.65625 y: 369.00528
504: Action moveH x: 208.125 y: 378.2587
504: Action moveH x: 209.53125 y: 397.60675
504: Action moveH x: 209.53125 y: 400.97162
508: Action moveH x: 210.0 y: 404.3365
508: Action moveH x: 210.0 y: 407.7014
508: Action moveH x: 210.0 y: 411.90747
508: Action moveH x: 205.78125 y: 345.4511
508: Action moveH x: 207.1875 y: 362.2755
508: Action moveH x: 207.65625 y: 369.00528
508: Action moveH x: 208.125 y: 378.2587
508: Action moveH x: 209.53125 y: 397.60675
508: Action moveH x: 209.53125 y: 400.97162
508: Action moveH x: 210.0 y: 404.3365
508: Action moveH x: 210.0 y: 407.7014
508: Action moveH x: 210.0 y: 411.90747
508: Action moveH x: 205.78125 y: 345.4511
508: Action moveH x: 207.1875 y: 362.2755
508: Action moveH x: 207.65625 y: 369.00528
508: Action moveH x: 208.125 y: 378.2587
508: Action moveH x: 209.53125 y: 397.60675
508: Action moveH x: 209.53125 y: 400.97162
512: Action moveH x: 210.0 y: 404.3365
512: Action moveH x: 210.0 y: 407.7014
512: Action moveH x: 210.0 y: 411.90747
512: Action moveH x: 205.78125 y: 345.4511
512: Action moveH x: 207.1875 y: 362.2755
512: Action moveH x: 207.65625 y: 369.00528
512: Action moveH x: 208.125 y: 378.2587
512: Action moveH x: 209.53125 y: 397.60675
512: Action moveH x: 209.53125 y: 400.97162
512: Action moveH x: 210.0 y: 404.3365
512: Action moveH x: 210.0 y: 407.7014
512: Action moveH x: 210.0 y: 411.90747
512: Action moveH x: 205.78125 y: 345.4511
515: Action moveH x: 207.1875 y: 362.2755
515: Action moveH x: 207.65625 y: 369.00528
515: Action moveH x: 208.125 y: 378.2587
515: Action moveH x: 209.53125 y: 397.60675
515: Action moveH x: 209.53125 y: 400.97162
515: Action moveH x: 210.0 y: 404.3365
515: Action moveH x: 210.0 y: 407.7014
515: Action moveH x: 210.0 y: 411.90747
515: Action moveH x: 205.78125 y: 345.4511
515: Action moveH x: 207.1875 y: 362.2755
515: Action moveH x: 207.65625 y: 369.00528
515: Action moveH x: 208.125 y: 378.2587
515: Action moveH x: 209.53125 y: 397.60675
515: Action moveH x: 209.53125 y: 400.97162
515: Action moveH x: 210.0 y: 404.3365
515: Action moveH x: 210.0 y: 407.7014
515: Action moveH x: 210.0 y: 411.90747
519: Action moveH x: 205.78125 y: 345.4511
519: Action moveH x: 207.1875 y: 362.2755
519: Action moveH x: 207.65625 y: 369.00528
519: Action moveH x: 208.125 y: 378.2587
519: Action moveH x: 209.53125 y: 397.60675
519: Action moveH x: 209.53125 y: 400.97162
519: Action moveH x: 210.0 y: 404.3365
519: Action moveH x: 210.0 y: 407.7014
519: Action moveH x: 210.0 y: 411.90747
523: Action moveH x: 205.78125 y: 345.4511
523: Action moveH x: 207.1875 y: 362.2755
523: Action moveH x: 207.65625 y: 369.00528
527: Action moveH x: 208.125 y: 378.2587
527: Action moveH x: 209.53125 y: 397.60675
527: Action moveH x: 209.53125 y: 400.97162
527: Action moveH x: 210.0 y: 404.3365
527: Action moveH x: 210.0 y: 407.7014
527: Action moveH x: 210.0 y: 411.90747
527: Action moveH x: 205.78125 y: 345.4511
527: Action moveH x: 207.1875 y: 362.2755
527: Action moveH x: 207.65625 y: 369.00528
527: Action moveH x: 208.125 y: 378.2587
527: Action moveH x: 209.53125 y: 397.60675
527: Action moveH x: 209.53125 y: 400.97162
527: Action moveH x: 210.0 y: 404.3365
527: Action moveH x: 210.0 y: 407.7014
527: Action moveH x: 210.0 y: 411.90747
531: Action moveH x: 205.78125 y: 345.4511
531: Action moveH x: 207.1875 y: 362.2755
531: Action moveH x: 207.65625 y: 369.00528
531: Action moveH x: 208.125 y: 378.2587
531: Action moveH x: 209.53125 y: 397.60675
531: Action moveH x: 209.53125 y: 400.97162
531: Action moveH x: 210.0 y: 404.3365
531: Action moveH x: 210.0 y: 407.7014
531: Action moveH x: 210.0 y: 411.90747
531: Action moveH x: 205.78125 y: 345.4511
531: Action moveH x: 207.1875 y: 362.2755
531: Action moveH x: 207.65625 y: 369.00528
531: Action moveH x: 208.125 y: 378.2587
531: Action moveH x: 209.53125 y: 397.60675
531: Action moveH x: 209.53125 y: 400.97162
531: Action moveH x: 210.0 y: 404.3365
531: Action moveH x: 210.0 y: 407.7014
535: Action moveH x: 210.0 y: 411.90747
535: Action moveH x: 205.78125 y: 345.4511
535: Action moveH x: 207.1875 y: 362.2755
535: Action moveH x: 207.65625 y: 369.00528
535: Action moveH x: 208.125 y: 378.2587
535: Action moveH x: 209.53125 y: 397.60675
535: Action moveH x: 209.53125 y: 400.97162
535: Action moveH x: 210.0 y: 404.3365
535: Action moveH x: 210.0 y: 407.7014
535: Action moveH x: 210.0 y: 411.90747
535: Action moveH x: 205.78125 y: 345.4511
535: Action moveH x: 207.1875 y: 362.2755
535: Action moveH x: 207.65625 y: 369.00528
535: Action moveH x: 208.125 y: 378.2587
535: Action moveH x: 209.53125 y: 397.60675
535: Action moveH x: 209.53125 y: 400.97162
535: Action moveH x: 210.0 y: 404.3365
535: Action moveH x: 210.0 y: 407.7014
535: Action moveH x: 210.0 y: 411.90747
535: Action moveH x: 205.78125 y: 345.4511
539: Action moveH x: 207.1875 y: 362.2755
539: Action moveH x: 207.65625 y: 369.00528
539: Action moveH x: 208.125 y: 378.2587
539: Action moveH x: 209.53125 y: 397.60675
539: Action moveH x: 209.53125 y: 400.97162
539: Action moveH x: 210.0 y: 404.3365
539: Action moveH x: 210.0 y: 407.7014
539: Action moveH x: 210.0 y: 411.90747
539: Action moveH x: 205.78125 y: 345.4511
539: Action moveH x: 207.1875 y: 362.2755
539: Action moveH x: 207.65625 y: 369.00528
539: Action moveH x: 208.125 y: 378.2587
539: Action moveH x: 209.53125 y: 397.60675
539: Action moveH x: 209.53125 y: 400.97162
539: Action moveH x: 210.0 y: 404.3365
539: Action moveH x: 210.0 y: 407.7014
539: Action moveH x: 210.0 y: 411.90747
539: Action moveH x: 205.78125 y: 345.4511
539: Action moveH x: 207.1875 y: 362.2755
539: Action moveH x: 207.65625 y: 369.00528
543: Action moveH x: 208.125 y: 378.2587
543: Action moveH x: 209.53125 y: 397.60675
543: Action moveH x: 209.53125 y: 400.97162
543: Action moveH x: 210.0 y: 404.3365
543: Action moveH x: 210.0 y: 407.7014
543: Action moveH x: 210.0 y: 411.90747
543: Action moveH x: 205.78125 y: 345.4511
543: Action moveH x: 207.1875 y: 362.2755
543: Action moveH x: 207.65625 y: 369.00528
543: Action moveH x: 208.125 y: 378.2587
543: Action moveH x: 209.53125 y: 397.60675
543: Action moveH x: 209.53125 y: 400.97162
543: Action moveH x: 210.0 y: 404.3365
543: Action moveH x: 210.0 y: 407.7014
543: Action moveH x: 210.0 y: 411.90747
543: Action moveH x: 205.78125 y: 345.4511
543: Action moveH x: 207.1875 y: 362.2755
543: Action moveH x: 207.65625 y: 369.00528
543: Action moveH x: 208.125 y: 378.2587
543: Action moveH x: 209.53125 y: 397.60675
543: Action moveH x: 209.53125 y: 400.97162
543: Action moveH x: 210.0 y: 404.3365
543: Action moveH x: 210.0 y: 407.7014
543: Action moveH x: 210.0 y: 411.90747
547: Action moveH x: 205.78125 y: 345.4511
547: Action moveH x: 207.1875 y: 362.2755
547: Action moveH x: 207.65625 y: 369.00528
547: Action moveH x: 208.125 y: 378.2587
547: Action moveH x: 209.53125 y: 397.60675
547: Action moveH x: 209.53125 y: 400.97162
547: Action moveH x: 210.0 y: 404.3365
547: Action moveH x: 210.0 y: 407.7014
547: Action moveH x: 210.0 y: 411.90747
547: Action moveH x: 205.78125 y: 345.4511
547: Action moveH x: 207.1875 y: 362.2755
547: Action moveH x: 207.65625 y: 369.00528
547: Action moveH x: 208.125 y: 378.2587
547: Action moveH x: 209.53125 y: 397.60675
547: Action moveH x: 209.53125 y: 400.97162
547: Action moveH x: 210.0 y: 404.3365
547: Action moveH x: 210.0 y: 407.7014
547: Action moveH x: 210.0 y: 411.90747
547: Action moveH x: 205.78125 y: 345.4511
547: Action moveH x: 207.1875 y: 362.2755
547: Action moveH x: 207.65625 y: 369.00528
547: Action moveH x: 208.125 y: 378.2587
547: Action moveH x: 209.53125 y: 397.60675
551: Action moveH x: 209.53125 y: 400.97162
551: Action moveH x: 210.0 y: 404.3365
551: Action moveH x: 210.0 y: 407.7014
551: Action moveH x: 210.0 y: 411.90747
551: Action moveH x: 205.78125 y: 345.4511
551: Action moveH x: 207.1875 y: 362.2755
551: Action moveH x: 207.65625 y: 369.00528
551: Action moveH x: 208.125 y: 378.2587
551: Action moveH x: 209.53125 y: 397.60675
551: Action moveH x: 209.53125 y: 400.97162
551: Action moveH x: 210.0 y: 404.3365
551: Action moveH x: 210.0 y: 407.7014
551: Action moveH x: 210.0 y: 411.90747
551: Action moveC [add point] x: 200 y: 400
551: [[Point(100, 100), Point(100, 200), Point(100, 300), Point(100, 400)], [Point(200, 100), Point(200, 200), Point(200, 400)]]
719: Action moveE x: 210.0 y: 424.52576
719: Action moveH x: 210.46875 y: 415.27234
719: Action moveH x: 210.46875 y: 418.63724
719: Action moveH x: 210.46875 y: 421.1609
これは私のdoDrawです(onDrawのように):
public void doDraw(Canvas canvas)
{
PathPoint xya = null;
canvas.drawColor(Color.WHITE);
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
int xPos = j * mNodeGap;
int yPos = i * mNodeGap;
try {
xya = new PathPoint(xPos, yPos, null);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mNodeCoordinates[i][j] = xya;
canvas.drawBitmap(mBitmap, xPos, yPos, null);
}
}
synchronized (mViewThread.getSurefaceHolder())
{
//draw path
for (Path path : mGraphics)
{
float aStartCoordinates[] = {0f, 0f};
float aEndCoordinates[] = {0f, 0f};
//get path values
PathMeasure pm = new PathMeasure(path, true);
pm.getPosTan(0f, aStartCoordinates, null);
//System.out.println("aStartCoordinates X:" + aStartCoordinates[0] + " aStartCoordinates Y:" + aStartCoordinates[1]);
pm.getPosTan(pm.getLength(), aEndCoordinates, null);
//System.out.println("aEndCoordinates X:" + aEndCoordinates[0] + " aEndCoordinates Y:" + aEndCoordinates[1]);
//coordinates are within game board boundaries
if((aStartCoordinates[0] >= 1 && aStartCoordinates[1] >= 1) && (aEndCoordinates[0] >= 1 && aEndCoordinates[1] >= 1))
{
canvas.drawPath(path, mPathPaint);
}
}
for (ArrayList<PathPoint> nodePattern : mNodesHitPatterns)
{
for (PathPoint nodeHit : nodePattern)
{
canvas.drawBitmap(mDotOK, nodeHit.x - ((mDotOK.getWidth()/2) - (mBitmap.getWidth()/2)), nodeHit.y - ((mDotOK.getHeight()/2) - (mBitmap.getHeight()/2)), null);
}
}
}
}
そしてonTouchEvent:
@Override
public boolean onTouchEvent(MotionEvent event) {
synchronized (mViewThread.getSurefaceHolder()) {
if(event.getAction() == MotionEvent.ACTION_DOWN)
{
System.out.println("Action downE x: " + event.getX() + " y: " + event.getY());
for (int i = 0; i < mGridSize; i++)
{
for (int j = 0; j < mGridSize; j++)
{
PathPoint pathPoint = mNodeCoordinates[i][j];
if((Math.abs((int)event.getX() - pathPoint.x) <= 35) && (Math.abs((int)event.getY() - pathPoint.y) <= 35))
{
//mPath.moveTo(pathPoint.x + mBitmap.getWidth() / 2, pathPoint.y + mBitmap.getHeight() / 2);
//System.out.println("Action down x: " + pathPoint.x + " y: " + pathPoint.y);
ArrayList<PathPoint> newNodesPattern = new ArrayList<PathPoint>();
mNodesHitPatterns.add(newNodesPattern);
//mNodesHitPatterns.add(nh);
// pathPoint.setAction("down");
break;
}
}
}
}
else if(event.getAction() == MotionEvent.ACTION_MOVE)
{
final int historySize = event.getHistorySize();
System.out.println("Action moveE x: " + event.getX() + " y: " + event.getY());
coordinateFound:
for (int i = 0; i < mGridSize; i++)
{
for (int j = 0; j < mGridSize; j++)
{
PathPoint pathPoint = mNodeCoordinates[i][j];
if((Math.abs((int)event.getX() - pathPoint.x) <= 35) && (Math.abs((int)event.getY() - pathPoint.y) <= 35))
{
int lastPatternIndex = mNodesHitPatterns.size()-1;
ArrayList<PathPoint> lastPattern = mNodesHitPatterns.get(lastPatternIndex);
int lastPatternLastNode = lastPattern.size()-1;
if(lastPatternLastNode != -1)
{
if(!pathPoint.equals(lastPattern.get(lastPatternLastNode).x, lastPattern.get(lastPatternLastNode).y))
{
lastPattern.add(pathPoint);
System.out.println("Action moveC [add point] x: " + pathPoint.x + " y: " + pathPoint.y);
}
}
else
{
lastPattern.add(pathPoint);
System.out.println("Action moveC [add point] x: " + pathPoint.x + " y: " + pathPoint.y);
}
break coordinateFound;
}
else //no current match => try historical
{
if(historySize > 0)
{
for (int k = 0; k < historySize; k++)
{
System.out.println("Action moveH x: " + event.getHistoricalX(k) + " y: " + event.getHistoricalY(k));
if((Math.abs((int)event.getHistoricalX(k) - pathPoint.x) <= 35) && (Math.abs((int)event.getHistoricalY(k) - pathPoint.y) <= 35))
{
int lastPatternIndex = mNodesHitPatterns.size()-1;
ArrayList<PathPoint> lastPattern = mNodesHitPatterns.get(lastPatternIndex);
int lastPatternLastNode = lastPattern.size()-1;
if(lastPatternLastNode != -1)
{
if(!pathPoint.equals(lastPattern.get(lastPatternLastNode).x, lastPattern.get(lastPatternLastNode).y))
{
lastPattern.add(pathPoint);
System.out.println("Action moveH [add point] x: " + pathPoint.x + " y: " + pathPoint.y);
}
}
else
{
lastPattern.add(pathPoint);
System.out.println("Action moveH [add point] x: " + pathPoint.x + " y: " + pathPoint.y);
}
break coordinateFound;
}
}
}
}
}
}
}
else if(event.getAction() == MotionEvent.ACTION_UP)
{
for (int i = 0; i < mGridSize; i++) {
for (int j = 0; j < mGridSize; j++) {
PathPoint pathPoint = mNodeCoordinates[i][j];
if((Math.abs((int)event.getX() - pathPoint.x) <= 35) && (Math.abs((int)event.getY() - pathPoint.y) <= 35))
{
//the location of the node
//mPath.lineTo(pathPoint.x + mBitmap.getWidth() / 2, pathPoint.y + mBitmap.getHeight() / 2);
//System.out.println("Action up x: " + pathPoint.x + " y: " + pathPoint.y);
//mGraphics.add(mPath);
// mNodesHit.add(pathPoint);
// pathPoint.setAction("up");
break;
}
}
}
}
System.out.println(mNodesHitPatterns.toString());
//create mPath
for (ArrayList<PathPoint> nodePattern : mNodesHitPatterns)
{
for (int i = 0; i < nodePattern.size(); i++)
{
if(i == 0) //first node in pattern
{
mPath.moveTo(nodePattern.get(i).x + mBitmap.getWidth() / 2, nodePattern.get(i).y + mBitmap.getHeight() / 2);
}
else
{
mPath.lineTo(nodePattern.get(i).x + mBitmap.getWidth() / 2, nodePattern.get(i).y + mBitmap.getHeight() / 2);
}
mGraphics.add(mPath);
}
}
return true;
}
}
============詳細情報==========================
問題は、なぜデバイスがそのように動作するのかということです。
これに関する入力に感謝します、D。