GestureDetector

1、手勢簡介

移動設備大行其道的今天,手勢是一個流行詞彙,那手勢是什麼呢?手,是人類各類創造性活動的自然工具,人們天生就會使用手的動做去表達情感,好比人們 會使用握手來表示友好,聾啞人使用一套用手語來代替語言交流,這些都是手勢在生活中的應用。可見自古以來手勢就是一套特定的語言系統,在人的交流中發揮重 要的做用。從交互上看,手勢其實是一種輸入模式。咱們如今在直觀意義上理解的人機交互是指人與機器之間的互動方式,這種互動方式經歷了鼠標、物理硬件、 屏幕觸控、遠距離的體感操做的逐步發展的過程。java

(引用自騰訊CDC-移動設備手勢設計初探android

對於開發者而言,如同按鈕的點擊同樣,手勢的觸發也是一種事件(Event)。而咱們一般將用戶的手指或者是可以觸發手勢的設備(好比觸控筆)在能識別手勢的設備(如觸摸屏)上的觸碰動做認爲是手勢事件。這樣的設計可以充分體現移動設備的交互優點,可以讓用戶以更加天然的方式參與到與應用的交互之中。git

下面列舉了一些常見的手勢操做:github

固然,每種手勢具體能用來作什麼,是由你的應用決定的,但咱們推薦你參考一些較新的移動互聯網應用開發規範來使得你的應用不那麼與世隔絕。app

對於一些常見的手勢,好比短按長按雙擊拖拽等,Android已實現了相應的手勢檢測,併爲其提供了相應的API(主要是監聽器)來知足開發須要。這些手勢將在本實驗被詳細的介紹。dom

而另一些很是規的手勢,例如在屏幕上畫個圈、畫一個特殊的幾何形狀等,Android沒有爲它們提供特定的手勢檢測,但容許開發者本身來添加手勢,經過與手勢類似度相關的API來負責識別。ide

2、在Android上實現手勢監聽

在Android中,是由GestureDetector類來負責手勢的檢測,每個GestureDetector類的實例都表明一個手勢監聽器。咱們在爲按鈕設置點擊事件監聽器時會用到OnClickListener,一樣,你在建立手勢監聽器時也須要一個相似的OnGestureListener實例。工具

OnGestureListerner接口裏面,有如下事件處理的方法可供你調用:佈局

-boolean onDown(MotionEvent e):當用戶在屏幕上按下時會觸發該方法,但在移動或擡起手指時不會觸發。字體

-void onShowPress(MotionEvent e):當用戶在屏幕上按下,而且既沒有移動有沒有擡起手指時,會觸發該方法。通常經過該方法告知用戶他們的動做已經被識別到了,你能夠高亮某個元素來提醒他們。

-boolean onSingleTapUp(MotionEvent e);:當用戶在屏幕上輕擊時(一般是指點擊屏幕的時間很短)會觸發該方法。

-boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY);:當用戶在屏幕上發起滾動的手勢時會觸發該方法。參數中的e1指第一個按下開始滾動的動做事件,e2指觸發當前這個方法的移動動做的事件,distanceXdistanceY則分別觸發onScroll方法期間的X、Y軸上的滾動距離,而不是指e1e2兩個事件發生直接的距離。

-void onLongPress(MotionEvent e);:當用戶在屏幕上持續地長按時會觸發該方法。

-boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY);:當用戶在屏幕上持續地按下而且有「拋」的動做時,會觸發該方法。對於該事件的理解,你能夠體會一下按住一個圖標而後把它扔到某個地方的感受。參數中的e1指第一個按下的動做事件,e2指觸發當前這個方法的「猛扔」動做的事件,velocityXvelocityY則分別觸發onFling方法期間X、Y軸上的移動速度。

若是你翻閱這些API的源代碼,你還能發現還有一個名爲OnDoubleTapListener的接口,顯然是雙擊事件的一個監聽器,它包含了下面這些方法。

-boolean onSingleTapConfirmed(MotionEvent e):當用戶在屏幕上單擊是會觸發此方法,與上面的onSingleTapUp方法不一樣的地方在於,該方法只會在監聽器肯定了用戶在第一次單擊後不會觸發雙擊事件時纔會被觸發。

-boolean onDoubleTap(MotionEvent e):當用戶在屏幕上雙擊時會觸發此方法。這裏的按下動做事件指的時雙擊中的第一次觸擊。

-boolean onDoubleTapEvent(MotionEvent e):在雙擊事件發生時會觸發此方法,包括了按下、移動和擡起事件。

掌握了上面這些方法後,咱們經過一個實例來實際應用一下:

實驗步驟主要有:

  1. (若你已在第二小節完成,請跳至下一步)使用Android Studio建立應用項目GesturePractice,包名爲com.shiyanlou.android.gesturepractice,基於Android 5.1。同時添加MainActivity及其佈局資源文件。在項目建立好以後再建立並打開AVD模擬器(鏡像選擇API22:Android 5.1.1)。
  2. res/layout/activity_main.xml資源文件放入一個文本標籤。
  3. MainActivity.java中,爲這個Activity添加手勢監聽相關的代碼。
  4. 編譯並運行這個應用,等待應用安裝至模擬器,在模擬器中試用該應用。

下面是res/layout/avtivity_main.xml中的佈局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:paddingBottom="@dimen/activity_vertical_margin"
                android:paddingLeft="@dimen/activity_horizontal_margin"
                android:paddingRight="@dimen/activity_horizontal_margin"
                android:paddingTop="@dimen/activity_vertical_margin"
                tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView_domain"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:text="Shiyanlou.com"
        android:textColor="#11AA8C"
        android:textSize="40dp"/>

    <TextView
        android:id="@+id/textView_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView_domain"
        android:layout_centerHorizontal="true"
        android:text="Gesture Practice"
        android:textColor="#000000"
        android:textSize="40dp"/>


    <TextView
        android:id="@+id/textView_helloWorld"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/bt_scroll"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="50dp"
        android:text="Hello World!"
        android:textColor="#000000"
    />
    <Button
        android:id="@+id/bt_scroll"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:layout_below="@id/textView_title"
        android:layout_marginTop="0dp"
        android:text="滑動我"/>
</RelativeLayout>

 

 

下面是MainActivity.java中的源代碼:

package com.earl.leangesturedetector;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements GestureDetector.OnGestureListener {//在這個類中須要實現OnGestureListener相關的接口
    private Button bt_scroll;
    private TextView textview;
    //聲明一個文本標籤
    private float fontSize = 30;
    //聲明一個用於指示字體大小的變量,初始值爲30
    GestureDetector detector;
    //聲明一個手勢檢測器對象

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bt_scroll = (Button) findViewById(R.id.bt_scroll);
        textview = (TextView) findViewById(R.id.textView_helloWorld);
        textview.setTextSize(fontSize);//實例化這個文本標籤併爲其設置最初始的大小

        detector = new GestureDetector(this, this);//實例化這個手勢檢測器對象

        //把事件都放在控件上
        bt_scroll.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                return detector.onTouchEvent(motionEvent);
            }
        });
    }

    //    //下面實現的這些接口負責處理全部在該Activity上發生的觸碰屏幕相關的事件
    //    @Override
    //    public boolean onTouchEvent(MotionEvent e) {
    //        return detector.onTouchEvent(e);
    //    }


    @Override
    public boolean onDown(MotionEvent motionEvent) {
        return false;
    }

    @Override
    public void onShowPress(MotionEvent motionEvent) {

    }

    @Override
    public boolean onSingleTapUp(MotionEvent motionEvent) {
        return false;
    }

    @Override
    public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float distanceX, float distanceY) {
        if (distanceY >= 0) {
            //和distanceX同樣,distanceY這個參數有正有負,咱們對該數值所處的不一樣範圍分別處理
            //向上滾動的手勢可讓文本標籤的字號變小
            if (fontSize > 10)
                fontSize -= 5;
            //加一個判斷的目的是防止字號過小或者太大,下同
            textview.setTextSize(fontSize);
            //將計算好的字號應用到文本標籤上
        } else {
            //向下滾動的手勢可讓文本標籤的字號變小
            if (fontSize < 60)
                fontSize += 5;
            textview.setTextSize(fontSize);
        }
        return true;
    }

    @Override
    public void onLongPress(MotionEvent motionEvent) {

    }

    @Override
    public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
        return false;
    }
}

 

 

檢查一下代碼,編譯並運行該應用,在模擬器上能夠看到應用的主界面:


 

此時你在屏幕上嘗試作出一些手勢,就能看到下方的Toast顯示剛剛觸發了哪些方法。

向上或向下滾動,你就能夠改變Hello World的字號大小了。

 
 
相關文章
相關標籤/搜索