Java 让最后一根手指接触屏幕

Java 让最后一根手指接触屏幕,java,android,multi-touch,motionevent,Java,Android,Multi Touch,Motionevent,我需要控制,我有多点触摸的问题 这个概念很简单: 如果用户触摸左侧(屏幕的一半),则船舶将向左移动 如果用户触摸右侧(屏幕的一半),则船舶将向右移动 当用户执行以下操作时,会出现问题: 把手指放在左边 在不取下左指的情况下,将手指放在右侧 取下左手手指 再次使用左手手指(我的代码无法识别它,这就是问题所在) 我想要一个只获取屏幕中最后一个手指的“X”位置的代码 我的实际代码: @Override public boolean onTouchEvent(MotionEvent ev

我需要控制,我有多点触摸的问题

这个概念很简单:

  • 如果用户触摸左侧(屏幕的一半),则船舶将向左移动
  • 如果用户触摸右侧(屏幕的一半),则船舶将向右移动
当用户执行以下操作时,会出现问题:

  • 把手指放在左边
  • 在不取下左指的情况下,将手指放在右侧
  • 取下左手手指
  • 再次使用左手手指(我的代码无法识别它,这就是问题所在)
我想要一个只获取屏幕中最后一个手指的“X”位置的代码

我的实际代码:

    @Override
public boolean onTouchEvent(MotionEvent event)
{
    int index = MotionEventCompat.getPointerCount(event) - 1;

    float x = (int) MotionEventCompat.getX(event, index);       
    @SuppressWarnings("deprecation")
    int ancho = AEngine.display.getWidth();

    switch (MotionEventCompat.getActionMasked(event))
    {
        case MotionEvent.ACTION_DOWN:
            if (gameView != null)
                gameView.touchNave(x, ancho);
            break;
        case MotionEvent.ACTION_POINTER_DOWN:
            if (gameView != null)
                gameView.touchNave(x, ancho);
            break;
        case MotionEvent.ACTION_MOVE:
            if (gameView != null)
                gameView.touchNave(x, ancho);
            break;

        case MotionEvent.ACTION_UP:
            Nave.estado = AEngine.NAVE_STAY;
            break;
        case MotionEvent.ACTION_POINTER_UP:
            Nave.estado = AEngine.NAVE_STAY;
            break;
    }


    return false;
}
我认为“屏幕上的最后一根手指”是指最新动作/动作指针停止时间的手指

每次获得DOWN/POINTER\u DOWN事件时,使用方法
getActionIndex()
获取操作指针的ID,然后
getPointerID()
,将其保留在字段“lastActionDownId”中


然后,在调用
touchNave()
之前,使用
findPointerIndex(lastActionDownId)
获取最后一个向下的索引。然后对方法调用的结果使用
getX(int index)

我通过使用LinkedHashMap并使用其代码的最后一项来创建它:

LinkedHashMap<Integer, Float> al = new LinkedHashMap<Integer, Float>();
@Override
public boolean onTouchEvent(MotionEvent event)
{
    int index = MotionEventCompat.getActionIndex(event);
    int id = event.getPointerId(index);

    float x = (int) MotionEventCompat.getX(event, index);


    @SuppressWarnings("deprecation")
    int ancho = AEngine.display.getWidth();

    switch (MotionEventCompat.getActionMasked(event))
    {
        case MotionEvent.ACTION_DOWN:
            anadir(id,x);               
            break;
        case MotionEvent.ACTION_POINTER_DOWN:
            anadir(id,x);
            break;

        case MotionEvent.ACTION_UP:
            al.remove(id);
            break;
        case MotionEvent.ACTION_POINTER_UP:         
            al.remove(id);
            break;
    }

    if(al.size() > 0)
    {
        if (gameView != null)
            gameView.touchNave(getX(al), ancho);
    }
    else 
    {
        Nave.estado = AEngine.NAVE_STAY;
    }

    return false;
}
public float getX(LinkedHashMap<Integer,Float> map) {
    Iterator<Map.Entry<Integer,Float>> iterator = map.entrySet().iterator();
    float x = 0;
    while (iterator.hasNext()) {
        x = iterator.next().getValue();
    }
    return x;
}

public void anadir(int id,float x)
{
    if (al.size() > 0 || !al.containsKey(id))
    {
        al.put(id, x);  
        Log.e("WTF",Integer.toString(id)+ "añadido");
    } 
}
LinkedHashMap al=新建LinkedHashMap();
@凌驾
公共布尔onTouchEvent(运动事件)
{
int index=MotionEventCompat.getActionIndex(事件);
int id=event.getPointerId(索引);
float x=(int)MotionEventCompat.getX(事件,索引);
@抑制警告(“弃用”)
intancho=AEngine.display.getWidth();
开关(MotionEventCompat.getActionMasked(事件))
{
case MotionEvent.ACTION\u DOWN:
阿纳迪尔(id,x);
打破
case MotionEvent.ACTION\u指针\u向下:
阿纳迪尔(id,x);
打破
case MotionEvent.ACTION\u UP:
al.移除(id);
打破
case MotionEvent.ACTION\u指针\u向上:
al.移除(id);
打破
}
如果(al.size()>0)
{
如果(gameView!=null)
gameView.touchNave(getX(al),ancho);
}
其他的
{
中堂空间=中堂空间;
}
返回false;
}
公共浮点getX(LinkedHashMap映射){
迭代器迭代器=map.entrySet().Iterator();
浮动x=0;
while(iterator.hasNext()){
x=迭代器.next().getValue();
}
返回x;
}
public void anadir(int id,float x)
{
如果(al.size()>0 | |!al.containsKey(id))
{
al.put(id,x);
Log.e(“WTF”,Integer.toString(id)+“añaddo”);
} 
}

我从来没有想到一个好的解决方案,最后我写了一个相当长的类。这似乎有点奇怪,但当你想正确地计算手指的数量,并考虑提升手指时,如果你给出触摸事件的数字,如#1和#2、#3等,你需要知道手指#2被提升了,因此手指#1和#3是有效的事件,下一次手指触摸再次是手指#2

有很多事情都是用多个手指进行的,用这种天真的方式会突然在屏幕上传送一个手指的位置,因为你按不同的顺序进行触摸。特别是如果你想储存这些触摸的信息

public class TouchTrack {

    private static final int INVALID = -1;
    private static final int POINTERMAX = 5;

    HashMap<Integer, TouchData> touches = new HashMap<>();
    ArrayList<TouchData> fingers = new ArrayList<>(POINTERMAX);


    public void setEventPointers(MotionEvent event) {
        int count = event.getPointerCount();
        count = Math.min(count, POINTERMAX);
        for (int i = 0; i < count; i++) {
            int id = event.getPointerId(i);
            TouchData td = touches.get(id);
            if (td == null) {
                //Log.e("Touch", "Log does not have records for ID: " + id);
                return;
            }
            td.x = event.getX(i);
            td.y = event.getY(i);
        }
    }

    public void setLostPointer(MotionEvent event) {
        int index = event.getActionIndex();
        if (index >= POINTERMAX) return;
        int id = event.getPointerId(index);
        TouchData finger = touches.get(id);
        finger.id = INVALID;
    }

    public void setNewPointer(MotionEvent event) {
        int index = event.getActionIndex();
        if (index >= POINTERMAX) return;
        int id = event.getPointerId(index);

        for (int i = 0; i < POINTERMAX; i++) {
            TouchData finger = fingers.get(i);
            if (finger.id == INVALID) {
                finger.id = id;
                finger.x = event.getX();
                finger.y = event.getY();
                touches.put(id, finger);
                break;
            }
        }
    }

    public double lastEventX(int requestIndex) {
        if ((requestIndex >= 0) && (requestIndex < POINTERMAX)) {
            TouchData td = fingers.get(requestIndex);
            if (td == null) return 0;
            return td.x;
        }
        return 0;
    }

    public double lastEventY(int requestIndex) {
        if ((requestIndex >= 0) && (requestIndex < POINTERMAX)) {
            TouchData td = fingers.get(requestIndex);
            if (td == null) return 0;
            return td.y;
        }
        return 0;
    }

    public boolean isPointerActive(int requestIndex) {
        if ((requestIndex >= 0) && (requestIndex < POINTERMAX)) {
            TouchData td = fingers.get(requestIndex);
            if (td == null) return false;
            return td.id != INVALID;
        }
        return false;
    }

    public void start(float x, float y) {
        touches.clear();
        fingers.clear();
        for (int i = 0; i < POINTERMAX; i++) {
            fingers.add(new TouchData(x, y));
        }
    }

    public void stop() {
        touches.clear();
        fingers.clear();
    }

    public class TouchData {
        static final int INVALID = -1;
        public int id = INVALID;
        public double x = 0;
        public double y = 0;

        public TouchData(double x, double y) {
            this.x = x;
            this.y = y;
        }
    }
}
公共类触摸屏{
私有静态final int INVALID=-1;
私有静态final int POINTERMAX=5;
HashMap touchs=新建HashMap();
ArrayList fingers=新的ArrayList(指针最大值);
公共void设置事件指针(MotionEvent事件){
int count=event.getPointerCount();
count=Math.min(count,POINTERMAX);
for(int i=0;i=指针最大值)返回;
int id=event.getPointerId(索引);
touchdatafinger=touchs.get(id);
finger.id=无效;
}
public void setNewPointer(运动事件){
int index=event.getActionIndex();
如果(索引>=指针最大值)返回;
int id=event.getPointerId(索引);
对于(int i=0;i=0)和&(requestIndex=0)和&(requestIndex=0)和&(requestIndex