为什么安卓onLong preSS总是onDoubleTap后被解雇? [英] Why android onLongPress always is fired after onDoubleTap?

查看:489
本文介绍了为什么安卓onLong preSS总是onDoubleTap后被解雇?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有onLong preSS,并根据此code置于按钮onDoubleTap行动:

  ...
GestureDetector探测器=新GestureDetector(这一点,新TapDetector());

公共无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.main);
    探测器=新GestureDetector(这一点,新TapDetector());
    ...
}

私有类TapDetector扩展GestureDetector.SimpleOnGestureListener {

    @覆盖
    公共布尔onDoubleTap(MotionEvent E){
        // 做一点事
        返回true;
    }

    @覆盖
     公共无效onLong preSS(MotionEvent E){
        // 做一点事
    }
}

按钮incomeButton =(按钮)findViewById(R.id.income);
button.setOnTouchListener(新OnTouchListener(){
    @覆盖
    公共布尔onTouch(视图V,MotionEvent事件){
        detector.onTouchEvent(事件);
        返回true;
    }
});
 

我总是看到onLong preSS解雇后onDoubleClick解雇和执行。什么是这种有悖常理的行为的原因,以及如何避免呢?

更新时间: 我已经改变了我的源$ C ​​$ C更具体

 公共类MainActivity延伸活动{
私人GestureDetector检测器;

@覆盖
公共无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.main);
    探测器=新GestureDetector(这一点,新TapDetector());

    Button按钮=(按钮)findViewById(R.id.button);
    button.setOnTouchListener(新OnTouchListener(){
        @覆盖
        公共布尔onTouch(视图V,MotionEvent事件){
            的System.out.println(************* onTouch *************);
            detector.onTouchEvent(事件);
            返回true;
        }
    });
}

类TapDetector扩展GestureDetector.SimpleOnGestureListener {

    @覆盖
     公共无效onLong preSS(MotionEvent E){
        的System.out.println(************* onLong preSS *************);
    }

    @覆盖
     公共布尔onDoubleTap(MotionEvent E){
        的System.out.println(************* onDoubleTap *************);
        意向意图=新的意图();
        intent.setClass(getApplicationContext(),NewActivity.class);
        intent.putExtra(参数名称,参数);
        startActivity(意向);
        返回true;
    }
}
}
 

这是以后的 onDoubleTap 我点击日志。你可以看到onLong preSS在最后 - 我从来不点击它

  I /的System.out(1106):************* onTouch *************
我/的System.out(1106):************* onTouch *************
我/的System.out(1106):************* onTouch *************
我/的System.out(1106):************* onDoubleTap *************
I / ActivityManager(59):启动活动:意向{CMP = my.tapdetector / .NewActivity(有群众演员)}
I / ActivityManager(59):显示活动my.tapdetector / .NewActivity:324毫秒(总324毫秒)
我/的System.out(1106):************* onLong preSS *************
 

更新我已经找到了解决方案。为了避免onLong preSS发射的两个的变化需要做的:

第一:detector.setIsLong pressEnabled(真正);在onTouch(视图V,MotionEvent事件)

  button.setOnTouchListener(新OnTouchListener(){
        @覆盖
        公共布尔onTouch(视图V,MotionEvent事件){
            的System.out.println(************* onTouch *************);
            detector.onTouchEvent(事件);
            detector.setIsLong pressEnabled(真正的);
            返回true;
        }
    });
 

二:添加detector.setIsLong pressEnabled();在onDoubleTap(MotionEvent E)

 公共布尔onDoubleTap(MotionEvent E){
        detector.setIsLong pressEnabled(假);
        的System.out.println(************* onDoubleTap *************);
        意向意图=新的意图();
        intent.setClass(getApplicationContext(),NewActivity.class);
        intent.putExtra(参数名称,参数);
        startActivity(意向);
        返回true;
    }
 

解决方案

从技术上讲这是不应该的。

 案例MotionEvent.ACTION_DOWN:
        mLastMotionX = X;
        mLastMotionY = Y;
        mCurrentDownEvent = MotionEvent.obtain(EV);
        mAlwaysInTa pregion = TRUE;
        闽龙preSS = FALSE;

        如果(mIsLong pressEnabled){
            mHandler.removeMessages(LONG_ preSS);
            mHandler.sendEmptyMessageAtTime(LONG_ $ P $干燥综合征,mCurrentDownEvent.getDownTime()
                    + tapTime +长pressTime);
        }
        mHandler.sendEmptyMessageAtTime(SHOW_ $ P $干燥综合征,mCurrentDownEvent.getDownTime()+ tapTime);
 

由于在ACTION_DOWN或ACTION_UP事件,所有的LONG_ $ P $的干燥综合征的消息事件从队列中删除。因此,在第二水龙头下面code将删除长preSS事件。

  mHandler.removeMessages(LONG_ preSS);
 

  

忍者编辑:哈克解决方法您的问题

  @覆盖
     公共无效onLong preSS(MotionEvent E){
        如果(MainActivity.this.hasWindowFocus())
        {
            Log.d(暴躁,长按);
        }
    }
 

I have onLongPress and onDoubleTap actions placed on the button according to this code:

...
GestureDetector detector = new GestureDetector(this, new TapDetector());

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main); 
    detector = new GestureDetector(this, new TapDetector());
    ... 
}

private class TapDetector extends GestureDetector.SimpleOnGestureListener { 

    @Override
    public boolean onDoubleTap(MotionEvent e) {
        // Do something
        return true;
    }

    @Override
     public void onLongPress(MotionEvent e) {          
        // Do something          
    }
}

Button incomeButton = (Button) findViewById(R.id.income);
button.setOnTouchListener(new OnTouchListener(){
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        detector.onTouchEvent(event);
        return true;
    }
});

I always see onLongPress fired after onDoubleClick fired and executed. What is the reason of such counterintuitive behavior and how to avoid it?

UPDATED I have changed my source code to be more specific

public class MainActivity extends Activity { 
private GestureDetector detector;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main); 
    detector = new GestureDetector(this, new TapDetector());    

    Button button = (Button) findViewById(R.id.button);                 
    button.setOnTouchListener(new OnTouchListener(){
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            System.out.println("************* onTouch *************");
            detector.onTouchEvent(event);
            return true;
        }
    });                        
}       

class TapDetector extends GestureDetector.SimpleOnGestureListener {  

    @Override
     public void onLongPress(MotionEvent e) {
        System.out.println("************* onLongPress *************");                    
    }         

    @Override
     public boolean onDoubleTap(MotionEvent e) {
        System.out.println("************* onDoubleTap *************");  
        Intent intent = new Intent();        
        intent.setClass(getApplicationContext(), NewActivity.class);
        intent.putExtra("parameterName", "parameter");
        startActivity(intent);              
        return true;
    }             
}        
}

This is a log after onDoubleTap I clicked. You can see onLongPress at the end - I never click it.

I/System.out( 1106): ************* onTouch *************
I/System.out( 1106): ************* onTouch *************
I/System.out( 1106): ************* onTouch *************
I/System.out( 1106): ************* onDoubleTap *************
I/ActivityManager(   59): Starting activity: Intent { cmp=my.tapdetector/.NewActivity (has extras) }
I/ActivityManager(   59): Displayed activity my.tapdetector/.NewActivity: 324 ms (total 324 ms)
I/System.out( 1106): ************* onLongPress *************

UPDATE I have found the solution. To avoid onLongPress firing two changes needs to be done:

First: detector.setIsLongpressEnabled(true); in onTouch(View v, MotionEvent event)

    button.setOnTouchListener(new OnTouchListener(){
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            System.out.println("************* onTouch *************");
            detector.onTouchEvent(event);
            detector.setIsLongpressEnabled(true);
            return true;
        }
    });

Second: add detector.setIsLongpressEnabled(false); in onDoubleTap(MotionEvent e)

     public boolean onDoubleTap(MotionEvent e) {
        detector.setIsLongpressEnabled(false);
        System.out.println("************* onDoubleTap *************");  
        Intent intent = new Intent();        
        intent.setClass(getApplicationContext(), NewActivity.class);
        intent.putExtra("parameterName", "parameter");
        startActivity(intent);             
        return true;
    }

解决方案

Technically this shouldn't happen

case MotionEvent.ACTION_DOWN:
        mLastMotionX = x;
        mLastMotionY = y;
        mCurrentDownEvent = MotionEvent.obtain(ev);
        mAlwaysInTapRegion = true;
        mInLongPress = false;

        if (mIsLongpressEnabled) {
            mHandler.removeMessages(LONG_PRESS);
            mHandler.sendEmptyMessageAtTime(LONG_PRESS, mCurrentDownEvent.getDownTime()
                    + tapTime + longpressTime);
        }
        mHandler.sendEmptyMessageAtTime(SHOW_PRESS, mCurrentDownEvent.getDownTime() + tapTime);

because on the ACTION_DOWN or ACTION_UP event, all of the LONG_PRESS messages events are removed from the queue. So on the second tap the following code will remove the long press events.

 mHandler.removeMessages(LONG_PRESS);

Ninja edit : hacky workaround for your problem

     @Override
     public void onLongPress(MotionEvent e) {
        if(MainActivity.this.hasWindowFocus())
        {
            Log.d("Touchy", "Long tap");    
        }
    }

这篇关于为什么安卓onLong preSS总是onDoubleTap后被解雇?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆