GestureDetector類

  • GestureDetector為手勢識(shí)別類,用來監(jiān)聽回調(diào)用戶對視圖的操作。
    這次我們就分別模擬一些用戶的手勢事件,來看看這個(gè)類是怎么回調(diào)的吧
    廢話不多說,直接看代碼。
    public class MainActivity extends AppCompatActivity {
    private Button mButton;
    private GestureDetector mGestureDetector;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.button);
    mGestureDetector = new GestureDetector(this, new MyOnGestureListener());
    mButton = (Button) findViewById(R.id.btn_textgesture);
    mButton.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
    Log.i(getClass().getName(), "onTouch-----" +
    getActionName(event.getAction()));
    mGestureDetector.onTouchEvent(event);
    // 一定要返回true,不然獲取不到完整的事件
    return true;
    }
    });
    }
    private String getActionName(int action) {
    String name = "";
    switch (action) {
    case MotionEvent.ACTION_DOWN: {
    name = "ACTION_DOWN";
    break;
    }
    case MotionEvent.ACTION_MOVE: {
    name = "ACTION_MOVE";
    break;
    }
    case MotionEvent.ACTION_UP: {
    name = "ACTION_UP";
    break;
    }
    default:
    break;
    }
    return name;
    }
    class MyOnGestureListener extends GestureDetector.SimpleOnGestureListener {
    @Override
    public boolean onSingleTapUp(MotionEvent e) {
    Log.i(getClass().getName(), "onSingleTapUp-----" +
    getActionName(e.getAct ion()));
    return false;
    }
    @Override
    public void onLongPress(MotionEvent e) {
    Log.i(getClass().getName(), "onLongPress-----" +
    getActionName(e.getAction()));
    }
    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2,float distanceX, float distanceY) {
    Log.i(getClass().getName(),"onScroll-----" +
    getActionName(e2.getAction()) + ",(" + e1.getX() + "," +
    e1.getY() + ") ,("+ e2.getX() + "," + e2.getY() + ")");
    return false;
    }
    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
    Log.i(getClass().getName(),"onFling-----" +
    getActionName(e2.getAction()) + ",(" + e1.getX() + "," + e1.getY()
    + ") ,("+ e2.getX() + "," + e2.getY() + ")");
    return false;
    }
    @Override
    public void onShowPress(MotionEvent e) {
    Log.i(getClass().getName(), "onShowPress-----" +
    getActionName(e.getAction()));
    }
    @Override
    public boolean onDown(MotionEvent e) {
    Log.i(getClass().getName(), "onDown-----" +
    getActionName(e.getAction()));
    return false;
    }
    @Override
    public boolean onDoubleTap(MotionEvent e) {
    Log.i(getClass().getName(), "onDoubleTap-----" +
    getActionName(e.getAction()));
    return false;
    }
    @Override
    public boolean onDoubleTapEvent(MotionEvent e) {
    Log.i(getClass().getName(), "onDoubleTapEvent-----" +
    getActionName(e.getAction()));
    return false;
    }
    @Override
    public boolean onSingleTapConfirmed(MotionEvent e) {
    Log.i(getClass().getName(), "onSingleTapConfirmed-----" + getActionName(e.getAction()));
    return false;
    }
    }
    }

視圖的樣子就是一個(gè)空布局里面有一個(gè)button,準(zhǔn)備工作都做好了。

  • 我們來模擬一下單次點(diǎn)擊事件:

單次點(diǎn)擊Log

這里由于筆者點(diǎn)擊時(shí)抖動(dòng)了一下,所以多調(diào)用了一次<code>onTouch</code>這并不影響我們觀察,根據(jù)Log的順序分析,首先調(diào)用了<code>onTouch</code>Motion是Down,之后馬上調(diào)用<code>onDown</code>,Motion同上,這時(shí)我們應(yīng)該把抬起來了,所以調(diào)用了<code>onTouch</code>而Motion是Up,最后調(diào)用<code>onSingleTapUp</code>是一次單擊事件,而最后那個(gè)<code>onSingleTapComfirmed</code>方法是用來判斷這就是一次點(diǎn)擊,一旦調(diào)用這個(gè)方法,后面就不會(huì)出現(xiàn)兩次點(diǎn)擊(雙擊)這樣的事件
,這里筆者有個(gè)問題:為什么調(diào)用<code>onSingleTapComfirmed</code>的Motion是Down而不是Up?
如果哪位大神指導(dǎo)這個(gè)問題,麻煩在評(píng)論區(qū)指點(diǎn)下,謝啦。

  • 之后我們模擬一下雙擊的事件:


    雙擊Log

    這里依舊出現(xiàn)了Move的Motion...還是不影響觀察,繼第一次點(diǎn)擊之后觀察,<code>onTouch</code>依舊調(diào)用這里就不再說了,注意下<code>onDoubleTap</code>他在我們按下去的時(shí)候就已經(jīng)調(diào)用了,之后的方法<code>onDoubleTapEvent</code>就可以用來監(jiān)聽從雙擊第二次Down到第二次Up的所有事件。而且,如果調(diào)用了<code>onDoubleTap</code>,那之后就不能再調(diào)用<code>onSingleTapUp</code>和<code>onSingleTapComfirmed</code>了。

  • 接下來是長按效果的模擬:

長按Log

前面的都是一樣的,從<code>onShowPress</code>開始,這個(gè)是一個(gè)按下不滑動(dòng)時(shí)的調(diào)用,如果按的時(shí)間再長一點(diǎn)就會(huì)調(diào)用<code>onLongPress</code>這就是長按的實(shí)現(xiàn)。值得一提的是,如果長按執(zhí)行了,直到用戶Up,其他的事件都不會(huì)觸發(fā),如圖就是筆者長按后移動(dòng)后的Log。

  • 再來是移動(dòng)的模擬:
移動(dòng)Log

這里根據(jù)打印的Log可以發(fā)現(xiàn),調(diào)用了<code>onScroll</code>,這個(gè)方法獲取的坐標(biāo)指的不是滑動(dòng)的距離,而是距離上一次滑動(dòng)的坐標(biāo)。這里說的一次滑動(dòng)指的是一整個(gè)事件。最后的<code>onFling</code>這個(gè)字面意思是“拋”,就是滑動(dòng)后沒有停下就離開屏幕,如果不想調(diào)用這個(gè)方法,在滑動(dòng)之后要停一下,親測有效。

  • 最后一點(diǎn)值得注意的是,這些方法除了<code>onLongPress</code>沒有返回值,其他的方法都有返回值通過<code>onTouchEvent</code>返回至<code>onTouch</code>。

理解這個(gè)類的事件回調(diào)順序后,相信以后對用戶的交互事件處理有點(diǎn)幫助。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容