我有一个绘制点网格的应用程序(比如说 3x3)。要求用户在该网格上绘制一些东西。如果用户的手指触摸网格中的一个点,则该点被着色。此外,将在每两个触摸点之间画一条线。
问题 - event.getAction() 经常会错过 MotionEvent.ACTION_MOVE。我是什么意思?- 好吧,假设用户画了一条连接三个点的直线。通常第一个点会被着色,第三个(最后一个)点会被着色,但第二个(中间)点不会被着色。
所以我记录了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] - 手指一直向下,画了四个点,最后一个点是 [100, 400]。
- 第二条线也是从上到下绘制的,但您可以看到顶部的第三个点 [200, 300] 丢失了。
我无法解释,所以我记录了触摸事件:
- moveH 表示动作 MOVE + 历史数据
- moveC 表示动作 MOVE + 当前数据
- 当触摸点靠近网格上的一个点时 [添加点] 会被记录
- 不时打印出整个路径数组
如果您查看日志,您会看到在添加点 [200, 200] 之后,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.