Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/222.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android getPointerCount()不';I don’我并不总是意识到指针已被释放_Android_Multi Touch - Fatal编程技术网

Android getPointerCount()不';I don’我并不总是意识到指针已被释放

Android getPointerCount()不';I don’我并不总是意识到指针已被释放,android,multi-touch,Android,Multi Touch,我的Android多点触控导航系统似乎一切都很好,直到我发现,并非总是,但有时,当手指松开时,应用程序的核心无法识别该事件 我在屏幕上做了跟踪,我意识到当一个手指抬起而其他手指没有改变位置时(即使在x轴或y轴上也没有改变一个像素),getPointerCount()不会像它应该的那样减少它的值,而是在至少一个其他手指稍微移动时返回正确的值 下面是模拟这种效果的代码(一个完整的、非常简单的单类项目),APK也可用于手动安装()。请你的反馈,因为这是一个停止我的问题 apk中的应用程序在头textv

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

我在屏幕上做了跟踪,我意识到当一个手指抬起而其他手指没有改变位置时(即使在x轴或y轴上也没有改变一个像素),getPointerCount()不会像它应该的那样减少它的值,而是在至少一个其他手指稍微移动时返回正确的值

下面是模拟这种效果的代码(一个完整的、非常简单的单类项目),APK也可用于手动安装()。请你的反馈,因为这是一个停止我的问题

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

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 
{ 
    TextView[] textView = new TextView[6]; // 0:common metrics 1-5:finger details   
    int pointersCount = -1;
    int action = 0;
    int actionMasked = 0;
    String actionString = "NOT INIT";
    Display display;
    int iViewWidth = 0;

    int motionsCounter = 0;

    @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 < 6; i++ )
        {
            textView[i] = new TextView(this);
            textView[i].setWidth(iViewWidth);
            textView[i].setTextSize(16);
            textView[i].setTextColor(Color.WHITE);
            textView[i].setBackgroundColor(Color.BLACK);
            layout.addView(textView[i]);
        }
        textView[0].setText("Touch the screen to start");
        setContentView(layout);
    }

@Override 
public boolean onTouchEvent(MotionEvent event)  
{
    int i = 0;
    pointersCount = event.getPointerCount();
    action = event.getAction() & MotionEvent.ACTION_MASK;
    motionsCounter++;
    actionMasked = event.getActionMasked();
    if (action == MotionEvent.ACTION_DOWN ) 
        actionString = "DOWN";
    else if (action == MotionEvent.ACTION_POINTER_DOWN ) 
        actionString = "POINTER DOWN";
    else if (action == MotionEvent.ACTION_POINTER_UP ) 
        actionString = "POINTER UP";
    else if (action == MotionEvent.ACTION_MOVE )
        actionString = "MOVE";
    else if (action == MotionEvent.ACTION_UP )
    {
        actionString = "ALL UP";
        pointersCount = 0;
    }
    else
        actionString = "UNKNOWN(" + action + ")";

    textView[0].setText (pointersCount + " POINTERS. ACTION:[" + action +"] " + actionString + ". (MASKED:" + actionMasked +"). " + motionsCounter + " MOTIONS");

    for (i = 0; i < pointersCount; i++)
    {
        int x = (int) event.getX(i);
        int y = (int) event.getY(i);            
        int id = event.getPointerId(i);
        textView[i+1].setText("idx: " + i + " id: " + id + ". (" + x + "," + y +")");
    }
    for ( i = pointersCount; i < 5; i++ )
        textView[i+1].setText("- - - - - ");
    return true;
}
}
package com.example.moultitouch;
导入android.app.Activity;
导入android.graphics.Color;
导入android.os.Bundle;
导入android.view.Display;
导入android.view.MotionEvent;
导入android.widget.LinearLayout;
导入android.widget.TextView;
公共类MainActivity扩展了活动
{ 
TextView[]TextView=新建TextView[6];//0:常用指标1-5:手指详细信息
int指针计数=-1;
int action=0;
int actionMasked=0;
String actionString=“非初始化”;
显示;
int-iViewWidth=0;
int motionsconter=0;
@凌驾
创建时受保护的void(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity\u motion\u event);
display=getWindowManager().getDefaultDisplay();
iViewWidth=display.getWidth();
LinearLayout布局=新的LinearLayout(本);
布局。设置方向(线性布局。垂直);
对于(int i=0;i<6;i++)
{
textView[i]=新的textView(本);
textView[i].setWidth(iViewWidth);
textView[i].setTextSize(16);
text视图[i].setTextColor(Color.WHITE);
textView[i].setBackgroundColor(Color.BLACK);
layout.addView(textView[i]);
}
textView[0].setText(“触摸屏幕启动”);
setContentView(布局);
}
@凌驾
公共布尔onTouchEvent(运动事件)
{
int i=0;
pointersCount=event.getPointerCount();
action=event.getAction()&MotionEvent.action\u掩码;
MotionSconter++;
actionMasked=event.getActionMasked();
if(action==MotionEvent.action\u DOWN)
actionString=“向下”;
else if(action==MotionEvent.action\u指针\u向下)
actionString=“指针向下”;
else if(action==MotionEvent.action\u指针\u向上)
actionString=“指针向上”;
else if(action==MotionEvent.action\u MOVE)
actionString=“移动”;
else if(action==MotionEvent.action\u UP)
{
actionString=“全部启动”;
指针计数=0;
}
其他的
actionString=“未知(“+action+”);
textView[0].setText(指针计数+”指针。操作:[“+ACTION+”]”“+actionString+”(屏蔽:“+actionMasked+”)。+MotionSconter+”运动);
对于(i=0;i

谢谢

终于找到了!实际上,该方法的问题仍然存在,每当用户放置两个手指并抬起其中一个手指,同时保持另一个手指在屏幕上完全不动时,getPointerCount()仍然返回2而不是1,直到剩余的手指稍微改变其位置,即使压力发生微小变化。要解决此问题,请遵循以下算法:

1:在每次触摸事件中,将所有指针的x/y坐标和所有报告的指针计数(无论是否正确)保存在一个数组中

2:调用getActionIndex()获取屏幕上最后一次响应的指针的索引

3:如果(屏蔽)操作是action\u POINTER\u UP,请将pointerCounter与其以前的值进行比较。如果它是相同的,那么这就是“…干涉,我们必须!”的情况,在这种情况下,从这个索引开始,用一个索引的坐标拉动数组x/y中的所有元素

  • 手动将保持指针计数的变量减少1
  • 问题已经解决。多谢各位

     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;
     }
     }
    
    package com.example.moultitouch;
    导入android.app.Activity;
    导入android.graphics.Color;
    导入android.os.Bundle;
    导入android.view.Display;
    导入android.view.MotionEvent;
    导入android.widget.LinearLayout;
    导入android.widget.TextView;
    公共类MainActivity扩展了活动
    {
    最终静态int MAX_支持的_指针=5;
    TextView[]TextView=new TextView[MAX_-SUPPORTED_-POINTERS+1];//0:常用指标1-5:手指详细信息
    显示;
    int pointersCount=0;
    int prevPointersCount=0;
    int actionMasked=0;
    int-iViewWidth=0;
    int lastLiftedPointerIdx=0;
    //只是为了寻找原因。
    String actionString=“非初始化”;
    字符串sHeader=“”;
    字符串sAlarm=“”;
    int motionsconter=0;
    int[]touch_x=新int[支持的最大指针];
    int[]touch_y=新int[支持的最大指针];
    int[]pointerID=new int[MAX_-SUPPORTED_-POINTERS];
    @凌驾
    创建时受保护的void(Bundle savedInstanceState)
    {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity\u motion\u event);
    display=getWindowManager().getDefaultDisplay