0

我有一个绘制点网格的应用程序(比如说 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 包含所有路径

  1. 网格在 X 和 Y 轴上分别编号为 0、100、200、300、400
  2. 第一个晕倒的点是 [100, 100] - 手指一直向下,画了四个点,最后一个点是 [100, 400]。
  3. 第二条线也是从上到下绘制的,但您可以看到顶部的第三个点 [200, 300] 丢失了。

我无法解释,所以我记录了触摸事件:

  1. moveH 表示动作 MOVE + 历史数据
  2. moveC 表示动作 MOVE + 当前数据
  3. 当触摸点靠近网格上的一个点时 [添加点] 会被记录
  4. 不时打印出整个路径数组

如果您查看日志,您会看到在添加点 [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.

4

1 回答 1

0

我找到了有关单点触控的教程:http ://www.vogella.com/articles/AndroidTouch/article.html 您可以实现并运行它以确保您的硬件正常工作。问题可能是您评估 event.getAction() 的方式 此外,如果您使用了事件,则当您覆盖 boolean onTouch 返回 tru 时。

于 2013-03-24T10:50:13.310 回答