簡體   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