繁体   English   中英

android - 从未调用 MotionEvent.ACTION_UP

[英]android - MotionEvent.ACTION_UP is never called

我想做一些工作,而用户将手放在视图上并在他松开时停止。 我的代码如下:

viewHolder.plus.setOnTouchListener(new View.OnTouchListener() {
        private Handler mHandler;
        @Override
        public boolean onTouch(View view, MotionEvent event) {
            switch(event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    if(mHandler==null)
                        mHandler = new Handler();
                    mHandler.postDelayed(mAction, 500);
                    return true;
                case MotionEvent.ACTION_UP:
                    Log.v("this","cancel");
                    if (mHandler != null) {
                        mHandler.removeCallbacks(mAction);
                        mHandler = null;
                        Log.v("this", "c cancel");
                    }
                    break;
            }
            return false;
        }

        Runnable mAction = new Runnable() {
            @Override public void run() {
                ChangeTedad(item.getid(), "plus");
                Log.v("this","Cc");
                mHandler.postDelayed(this, 500);
            }
        };

    });

问题是,永远不会调用 ACTION_UP 并且 runnable 会永远运行。

当用户取消触摸时如何停止运行?

您没有在触摸事件中正确设置中断和返回标志。

请替换为您的代码,

viewHolder.plus.setOnTouchListener(new View.OnTouchListener() {
        private Handler mHandler;
        @Override
        public boolean onTouch(View view, MotionEvent event) {
            switch(event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    if(mHandler==null)
                        mHandler = new Handler();
                    mHandler.postDelayed(mAction, 500);
                    break;
                case MotionEvent.ACTION_UP:
                    Log.v("this","cancel");
                    if (mHandler != null) {
                        mHandler.removeCallbacks(mAction);
                        mHandler = null;
                        Log.v("this", "c cancel");
                    }
                    break;
            }
            return true;
        }

        Runnable mAction = new Runnable() {
            @Override public void run() {
                ChangeTedad(item.getid(), "plus");
                Log.v("this","Cc");
                mHandler.postDelayed(this, 500);
            }
        };
    });

希望这个能对您有所帮助

每当您在视图中进行单次触摸时,Android都会创建a series of touch events而不是a single touch event并缓冲这些事件,然后根据该方法返回的值顺序调用onTouch方法。

例如,当您对视图进行一次触摸时,正常的事件顺序将是

  • ACTION_DOWN (当您放下手指时)
  • (可选) ACTION_MOVE (如果您在触摸屏幕时移动手指)
  • ACTION_UP (从屏幕上移开手指时)

但是,如果您响应ACTION_XXX事件而从onTouchEvent覆盖返回false ,则不会通知您任何后续事件(您的代码将不执行)。

回到您的情况,因为您从onTouchEvent返回false ,所以在接收到第一个事件( ACTION_DOWN )之后,将不调用所有后续事件(包括ACTION_UP )。

您需要做的就是从onTouchEvent方法返回true 而已!

viewHolder.plus.setOnTouchListener(new View.OnTouchListener() {
    private Handler mHandler;

    @Override
    public boolean onTouch(View view, MotionEvent event) {
        switch(event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (mHandler == null) {
                    mHandler = new Handler();
                }
                mHandler.postDelayed(mAction, 500);
                break;
            case MotionEvent.ACTION_UP:
                Log.v("this","cancel");
                if (mHandler != null) {
                    mHandler.removeCallbacks(mAction);
                    mHandler = null;
                    Log.v("this", "c cancel");
                }
                break;
        }

        // [IMPORTANT] Return true here
        return true;
    }

    Runnable mAction = new Runnable() {
        @Override public void run() {
            ChangeTedad(item.getid(), "plus");
            Log.v("this","Cc");
            mHandler.postDelayed(this, 500);
        }
    };
}); 

是一篇非常不错的文章,介绍了Android中的触摸处理。 有空的时候看看吧。

您还可以将ACTION_UP逻辑代码添加到ACTION_CANCEL ,因为如果您触摸视图并释放它,它将调用ACTION_UP ,但是如果您在视图中按下 state 并且您移动了 1 个像素,它不会调用ACTION_UP ,并且只调用ACTION_CANCEL 希望这对您有所帮助。

viewHolder.plus.setOnTouchListener(new View.OnTouchListener() {
        private Handler mHandler;
        @Override
        public boolean onTouch(View view, MotionEvent event) {
            switch(event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    if(mHandler==null)
                        mHandler = new Handler();
                    mHandler.postDelayed(mAction, 500);
                    return true;
                case MotionEvent.ACTION_UP:
                    Log.v("this","cancel");
                    if (mHandler != null) {
                        mHandler.removeCallbacks(mAction);
                        mHandler = null;
                        Log.v("this", "c cancel");
                    }
                    break;
                case MotionEvent.ACTION_CANCEL:
                    Log.v("this","cancel");
                    if (mHandler != null) {
                        mHandler.removeCallbacks(mAction);
                        mHandler = null;
                        Log.v("this", "c cancel");
                    }
                    break;
            }
            return false;
        }

        Runnable mAction = new Runnable() {
            @Override public void run() {
                ChangeTedad(item.getid(), "plus");
                Log.v("this","Cc");
                mHandler.postDelayed(this, 500);
            }
        };

    });

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM