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