getPointerCount()并不总是识别指针已被释放

时间:2017-02-09 13:11:31

标签: android multi-touch

Android中的多点触控导航系统似乎一切都很好,直到我发现,并非总是但有时,当手指被释放时,应用程序的核心无法识别此事件。

我放在屏幕上的痕迹,我意识到当手指抬起而其他手指没有改变位置(甚至不是x或y轴中的单个像素)时,getPointerCount()不应该减少它的值,但是一旦其他手指中的至少一个略微移动,就会返回正确的值。

Bellow,是模拟此效果的代码(一个完整的,非常简单的一流项目),APK也可用于手动安装(www.liknongames.com/apps/MultiTouch.apk)。请您提供反馈,因为这对我来说是个问题。

apk中的应用程序,在header-textview(textView [0])中报告活动指针,当前操作(屏蔽和未屏蔽)以及onTouchEvent()方法调用的计数器。

Sub Extract()

    Dim RarIt As String
    Dim Source As String
    Dim Desti As String
    Dim WinRarPath As String

    WinRarPath = "C:\Program Files\WinRar\"
    Source = "C:\Reports\EMEA Load.rar"
    Desti = "C:\Reports\"

    RarIt = Shell(Chr(34) & WinRarPath & "WinRar.exe" & Chr(34) & " e " & Chr(34) & Source & Chr(34) & " " & Chr(34) & Desti & Chr(34), vbNormalFocus)

End Sub

谢谢

1 个答案:

答案 0 :(得分:0)

终于,我发现了!实际上,该方法的问题仍然存在,并且每当用户放置两个手指并抬起一个手指同时保持另一个绝对不动在屏幕上时,则getPointerCount()仍然返回2而不是1,直到剩下的手指稍微改变其位置,即使通过在压力上做出微小的改变。修复,遵循此算法:

1:在每个触摸事件中,在数组中保留所有指针的x / y坐标以及所有报告的指针数(无论它是否正确)

2:调用getActionIndex()获取最后在屏幕上反应的指针的索引。

3:如果(掩码)动作是ACTION_POINTER_UP,则将pointerCounter与其先前的值进行比较。如果它是相同的,那么这就是“...介入,我们必须!”因此,在这种情况下,从该索引开始,将数组x / y中的所有元素与坐标相乘一个索引。

  1. 手动,将保持指针计数的变量减少1。
  2. 问题已结束。谢谢。

     package com.example.moultitouch;
    
     import android.app.Activity;
     import android.graphics.Color;
     import android.os.Bundle;
     import android.view.Display;
     import android.view.MotionEvent;
     import android.widget.LinearLayout;
     import android.widget.TextView;
    
     public class MainActivity extends Activity
     {
     final static int MAX_SUPPORTED_POINTERS = 5;
    
     TextView[] textView = new TextView[MAX_SUPPORTED_POINTERS+1]; // 0:common metrics 1-5:finger details
     Display display;
    
     int pointersCount        =  0;
     int prevPointersCount    =  0;
     int actionMasked         =  0;
     int iViewWidth           =  0;
     int lastLiftedPointerIdx =  0;
    
     // just for tracing reason.
     String actionString = "NOT INIT";
     String sHeader = "";
     String sAlarm  = "";
     int motionsCounter = 0;
    
     int[] touch_x   = new int[MAX_SUPPORTED_POINTERS];
     int[] touch_y   = new int[MAX_SUPPORTED_POINTERS];
     int[] pointerID = new int[MAX_SUPPORTED_POINTERS];
    
     @Override
     protected void onCreate(Bundle savedInstanceState) 
     {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_motion_event);
         display = getWindowManager().getDefaultDisplay();
         iViewWidth  = display.getWidth();
         LinearLayout layout = new LinearLayout(this);
        layout.setOrientation(LinearLayout.VERTICAL);       
    
        for ( int i = 0; i < MAX_SUPPORTED_POINTERS+1; i++ )
        {
          textView[i] = new TextView(this);
          textView[i].setWidth(iViewWidth);
          textView[i].setTextSize(16);
          textView[i].setTextColor(Color.WHITE);
          textView[i].setBackgroundColor(Color.BLACK);
          textView[i].setText("_");
          layout.addView(textView[i]);
        }
        textView[0].setText("Touch the screen to start");
        bThreadForDisplay = true;
        setContentView(layout);
     }
    
    
     @Override 
     public boolean onTouchEvent(MotionEvent event)  
     {
          int i = 0, j = 0;
          prevPointersCount = pointersCount;
          pointersCount = event.getPointerCount();
          pointersCount = pointersCount > MAX_SUPPORTED_POINTERS ? MAX_SUPPORTED_POINTERS : pointersCount;
    
          // for ACTION_POINTER_DOWN or ACTION_POINTER_UP as returned by getActionMasked(), 
          // returns the associated pointer index. 
          lastLiftedPointerIdx = event.getActionIndex();
          actionMasked = event.getActionMasked(); 
    
          for (i = 0; i < pointersCount; i++)
     {
          int x = (int) event.getX(i);
          int y = (int) event.getY(i);          
          touch_x[i] = x;
          touch_y[i] = y;
     }
    
          motionsCounter++;
          if (actionMasked == MotionEvent.ACTION_DOWN ) 
               actionString = "DOWN";
          else if (actionMasked == MotionEvent.ACTION_POINTER_DOWN )
               actionString = "POINTER DOWN";
          else if (actionMasked == MotionEvent.ACTION_POINTER_UP )
          {
               if ( prevPointersCount == pointersCount )
               {
                    sAlarm = " ALARM ON ID " + lastLiftedPointerIdx;
                    for ( int k = lastLiftedPointerIdx; k < pointersCount-1; k++ ) // from that point, elevate everything by one position 
                    {
                         touch_x[k]   = touch_x[k+1];
                         touch_y[k]   = touch_y[k+1];
                         pointerID[k] = pointerID[k+1];
                    }
                    pointersCount--; // correct the counter.
                    prevPointersCount = pointersCount;
               } // alarm case
               actionString = "POINTER UP";
          }
          else if (actionMasked == MotionEvent.ACTION_MOVE )
               actionString = "MOVE";
          else if (actionMasked == MotionEvent.ACTION_UP )
          {
               actionString = "ALL UP";
               pointersCount = 0;
          }
          else  actionString = "UNKNOWN(" + actionMasked + ")";
    
          sHeader = pointersCount + " POINTERS. ACTION:[" + actionMasked +"] " + actionString + ".  " + motionsCounter + " MOTIONS. " + sAlarm;
          if ( actionMasked == MotionEvent.ACTION_POINTER_UP )
               sHeader += sAlarm;
          textView[0].setText (sHeader);
    
          for (i = 0; i < pointersCount; i++)
               textView[i+1].setText("IDX: " + i + " ID: " + pointerID[i] + ". (" + touch_x[i] + "," + touch_y[i] +")");
          for ( i = pointersCount; i < MAX_SUPPORTED_POINTERS; i++ )
               textView[i+1].setText("- - - - - ");
    
        return true;
     }
     }