android view gesturedetector,如何在Android中利用 GestureDetector進行手勢檢測

如何在Android中利用 GestureDetector進行手勢檢測

發布時間:2020-11-26 16:15:21

來源:億速云

閱讀:92

作者:Leah

今天就跟大家聊聊有關如何在Android中利用 GestureDetector進行手勢檢測,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。

一、概述

當用戶觸摸屏幕的時候,會產生許多手勢,例如down,up,scroll,filing等等。

一般情況下,我們知道View類有個View.OnTouchListener內部接口,通過重寫他的onTouch(View v, MotionEvent event)方法,我們可以處理一些touch事件,但是這個方法太過簡單,如果需要處理一些復雜的手勢,用這個接口就會很麻煩(因為我們要自己根據用戶觸摸的軌跡去判斷是什么手勢)。

Android sdk給我們提供了GestureDetector(Gesture:手勢Detector:識別)類,通過這個類我們可以識別很多的手勢,主要是通過他的onTouchEvent(event)方法完成了不同手勢的識別。雖然他能識別手勢,但是不同的手勢要怎么處理,應該是提供給程序員實現的。

GestureDetector這個類對外提供了兩個接口和一個外部類

接口:OnGestureListener,OnDoubleTapListener

內部類:SimpleOnGestureListener

這個外部類,其實是兩個接口中所有函數的集成,它包含了這兩個接口里所有必須要實現的函數而且都已經重寫,但所有方法體都是空的;不同點在于:該類是static class,程序員可以在外部繼承這個類,重寫里面的手勢處理方法。

下面我們先看OnGestureListener接口;

二、GestureDetector.OnGestureListener---接口

1、基本講解如果我們寫一個類并implements OnGestureListener,會提示有幾個必須重寫的函數,加上之后是這個樣子的:private?class?gesturelistener?implements?GestureDetector.OnGestureListener{

public?boolean?onDown(MotionEvent?e)?{

//?TODO?Auto-generated?method?stub

return?false;

}

public?void?onShowPress(MotionEvent?e)?{

//?TODO?Auto-generated?method?stub

}

public?boolean?onSingleTapUp(MotionEvent?e)?{

//?TODO?Auto-generated?method?stub

return?false;

}

public?boolean?onScroll(MotionEvent?e1,?MotionEvent?e2,

float?distanceX,?float?distanceY)?{

//?TODO?Auto-generated?method?stub

return?false;

}

public?void?onLongPress(MotionEvent?e)?{

//?TODO?Auto-generated?method?stub

}

public?boolean?onFling(MotionEvent?e1,?MotionEvent?e2,?float?velocityX,

float?velocityY)?{

//?TODO?Auto-generated?method?stub

return?false;

}

}

可見,這里總共重寫了六個函數,這些函數都在什么情況下才會觸發呢,下面講一下:

OnDown(MotionEvent e):用戶按下屏幕就會觸發;

onShowPress(MotionEvent e):如果是按下的時間超過瞬間,而且在按下的時候沒有松開或者是拖動的,那么onShowPress就會執行,具體這個瞬間是多久,我也不清楚呃……

onLongPress(MotionEvent e):長按觸摸屏,超過一定時長,就會觸發這個事件

觸發順序:

onDown->onShowPress->onLongPress

onSingleTapUp(MotionEvent e):從名子也可以看出,一次單獨的輕擊抬起操作,也就是輕擊一下屏幕,立刻抬起來,才會有這個觸發,當然,如果除了Down以外還有其它操作,那就不再算是Single操作了,所以也就不會觸發這個事件

觸發順序:

點擊一下非常快的(不滑動)Touchup:

onDown->onSingleTapUp->onSingleTapConfirmed

點擊一下稍微慢點的(不滑動)Touchup:

onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed

onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY) :滑屏,用戶按下觸摸屏、快速移動后松開,由1個MotionEvent ACTION_DOWN, 多個ACTION_MOVE, 1個ACTION_UP觸發

參數解釋:

e1:第1個ACTION_DOWN MotionEvent

e2:最后一個ACTION_MOVE MotionEvent

velocityX:X軸上的移動速度,像素/秒

velocityY:Y軸上的移動速度,像素/秒

onScroll(MotionEvent e1, MotionEvent e2,float distanceX, float distanceY):在屏幕上拖動事件。無論是用手拖動view,或者是以拋的動作滾動,都會多次觸發,這個方法在ACTION_MOVE動作發生時就會觸發

滑屏:手指觸動屏幕后,稍微滑動后立即松開

onDown-----》onScroll----》onScroll----》onScroll----》………----->onFling

拖動:

onDown------》onScroll----》onScroll------》onFiling

可見,無論是滑屏,還是拖動,影響的只是中間OnScroll觸發的數量多少而已,最終都會觸發onFling事件!

2、實例

要使用GestureDetector,有三步要走:

1.創建OnGestureListener監聽函數:

可以使用構造實例:GestureDetector.OnGestureListener?listener?=?new?GestureDetector.OnGestureListener(){

};

也可以構造類:private?class?gestureListener?implements?GestureDetector.OnGestureListener{

}

2.創建GestureDetector實例mGestureDetector:

構造函數有下面三個,根據需要選擇:

GestureDetector gestureDetector=new GestureDetector(GestureDetector.OnGestureListener listener);

GestureDetector gestureDetector=new GestureDetector(Context context,GestureDetector.OnGestureListener listener);

GestureDetector gestureDetector=new GestureDetector(Context context,GestureDetector.SimpleOnGestureListener listener);

3、onTouch(View v, MotionEvent event)中攔截:public?boolean?onTouch(View?v,?MotionEvent?event)?{

return?mGestureDetector.onTouchEvent(event);

}

4.控件綁定TextView?tv?=?(TextView)findViewById(R.id.tv);

tv.setOnTouchListener(this);

現在進入實例階段:

首先,在主布局頁面添加一個textView,并將其放大到整屏,方便在其上的手勢識別,代碼為:

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context="com.example.gesturedetectorinterface.MainActivity"?>

android:id="@+id/tv"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:layout_margin="50dip"

android:background="#ff00ff"

android:text="@string/hello_world"?/>

然后在JAVA代碼中,依據上面的三步走原則,寫出代碼,并在所有的手勢下添加上Toast提示并寫上Logpublic?class?MainActivity?extends?Activity?implements?OnTouchListener{

private?GestureDetector?mGestureDetector;

@Override

protected?void?onCreate(Bundle?savedInstanceState)?{

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mGestureDetector?=?new?GestureDetector(new?gestureListener());?//使用派生自OnGestureListener

TextView?tv?=?(TextView)findViewById(R.id.tv);

tv.setOnTouchListener(this);

tv.setFocusable(true);

tv.setClickable(true);

tv.setLongClickable(true);

}

/*

*?在onTouch()方法中,我們調用GestureDetector的onTouchEvent()方法,將捕捉到的MotionEvent交給GestureDetector

*?來分析是否有合適的callback函數來處理用戶的手勢

*/

public?boolean?onTouch(View?v,?MotionEvent?event)?{

return?mGestureDetector.onTouchEvent(event);

}

private?class?gestureListener?implements?GestureDetector.OnGestureListener{

//?用戶輕觸觸摸屏,由1個MotionEvent?ACTION_DOWN觸發

public?boolean?onDown(MotionEvent?e)?{

Log.i("MyGesture",?"onDown");

Toast.makeText(MainActivity.this,?"onDown",?Toast.LENGTH_SHORT).show();

return?false;

}

/*

*?用戶輕觸觸摸屏,尚未松開或拖動,由一個1個MotionEvent?ACTION_DOWN觸發

*?注意和onDown()的區別,強調的是沒有松開或者拖動的狀態

*

*?而onDown也是由一個MotionEventACTION_DOWN觸發的,但是他沒有任何限制,

*?也就是說當用戶點擊的時候,首先MotionEventACTION_DOWN,onDown就會執行,

*?如果在按下的瞬間沒有松開或者是拖動的時候onShowPress就會執行,如果是按下的時間超過瞬間

*?(這塊我也不太清楚瞬間的時間差是多少,一般情況下都會執行onShowPress),拖動了,就不執行onShowPress。

*/

public?void?onShowPress(MotionEvent?e)?{

Log.i("MyGesture",?"onShowPress");

Toast.makeText(MainActivity.this,?"onShowPress",?Toast.LENGTH_SHORT).show();

}

//?用戶(輕觸觸摸屏后)松開,由一個1個MotionEvent?ACTION_UP觸發

///輕擊一下屏幕,立刻抬起來,才會有這個觸發

//從名子也可以看出,一次單獨的輕擊抬起操作,當然,如果除了Down以外還有其它操作,那就不再算是Single操作了,所以這個事件?就不再響應

public?boolean?onSingleTapUp(MotionEvent?e)?{

Log.i("MyGesture",?"onSingleTapUp");

Toast.makeText(MainActivity.this,?"onSingleTapUp",?Toast.LENGTH_SHORT).show();

return?true;

}

//?用戶按下觸摸屏,并拖動,由1個MotionEvent?ACTION_DOWN,?多個ACTION_MOVE觸發

public?boolean?onScroll(MotionEvent?e1,?MotionEvent?e2,

float?distanceX,?float?distanceY)?{

Log.i("MyGesture22",?"onScroll:"+(e2.getX()-e1.getX())?+"?"+distanceX);

Toast.makeText(MainActivity.this,?"onScroll",?Toast.LENGTH_LONG).show();

return?true;

}

//?用戶長按觸摸屏,由多個MotionEvent?ACTION_DOWN觸發

public?void?onLongPress(MotionEvent?e)?{

Log.i("MyGesture",?"onLongPress");

Toast.makeText(MainActivity.this,?"onLongPress",?Toast.LENGTH_LONG).show();

}

//?用戶按下觸摸屏、快速移動后松開,由1個MotionEvent?ACTION_DOWN,?多個ACTION_MOVE,?1個ACTION_UP觸發

public?boolean?onFling(MotionEvent?e1,?MotionEvent?e2,?float?velocityX,

float?velocityY)?{

Log.i("MyGesture",?"onFling");

Toast.makeText(MainActivity.this,?"onFling",?Toast.LENGTH_LONG).show();

return?true;

}

};

}

源碼在博客底部給出。

三、GestureDetector.OnDoubleTapListener---接口

1、構建

有兩種方式設置雙擊監聽:

方法一:新建一個類同時派生自OnGestureListener和OnDoubleTapListener:private?class?gestureListener?implements?GestureDetector.OnGestureListener,GestureDetector.OnDoubleTapListener{

}

方法二:使用GestureDetector::setOnDoubleTapListener();函數設置監聽://構建GestureDetector實例

mGestureDetector?=?new?GestureDetector(new?gestureListener());?//使用派生自OnGestureListener

private?class?gestureListener?implements?GestureDetector.OnGestureListener{

}

//設置雙擊監聽器

mGestureDetector.setOnDoubleTapListener(new?doubleTapListener());

private?class?doubleTapListener?implements?GestureDetector.OnDoubleTapListener{

}

注意:大家可以看到無論在方法一還是在方法二中,都需要派生自GestureDetector.OnGestureListener,前面我們說過GestureDetector 的構造函數,如下:

GestureDetector gestureDetector=new GestureDetector(GestureDetector.OnGestureListener listener);

GestureDetector gestureDetector=new GestureDetector(Context context,GestureDetector.OnGestureListener listener);

GestureDetector gestureDetector=new GestureDetector(Context context,GestureDetector.SimpleOnGestureListener listener);

可以看到,在構造函數中,除了后面要講的SimpleOnGestureListener 以外的其它兩個構造函數都必須是OnGestureListener的實例。所以要想使用OnDoubleTapListener的幾個函數,就必須先實現OnGestureListener。

2、函數講解

首先看一下OnDoubleTapListener接口必須重寫的三個函數:private?class?doubleTapListener?implements?GestureDetector.OnDoubleTapListener{

public?boolean?onSingleTapConfirmed(MotionEvent?e)?{

//?TODO?Auto-generated?method?stub

return?false;

}

public?boolean?onDoubleTap(MotionEvent?e)?{

//?TODO?Auto-generated?method?stub

return?false;

}

public?boolean?onDoubleTapEvent(MotionEvent?e)?{

//?TODO?Auto-generated?method?stub

return?false;

}

}

onSingleTapConfirmed(MotionEvent e):單擊事件。用來判定該次點擊是SingleTap而不是DoubleTap,如果連續點擊兩次就是DoubleTap手勢,如果只點擊一次,系統等待一段時間后沒有收到第二次點擊則判定該次點擊為SingleTap而不是DoubleTap,然后觸發SingleTapConfirmed事件。觸發順序是:OnDown->OnsingleTapUp->OnsingleTapConfirmed

關于onSingleTapConfirmed和onSingleTapUp的一點區別: OnGestureListener有這樣的一個方法onSingleTapUp,和onSingleTapConfirmed容易混淆。二者的區別是:onSingleTapUp,只要手抬起就會執行,而對于onSingleTapConfirmed來說,如果雙擊的話,則onSingleTapConfirmed不會執行。

onDoubleTap(MotionEvent e):雙擊事件

onDoubleTapEvent(MotionEvent e):雙擊間隔中發生的動作。指觸發onDoubleTap以后,在雙擊之間發生的其它動作,包含down、up和move事件;下圖是雙擊一下的Log輸出:

0e0a4a358eb16c9687a3120df368fd66.png

兩點總結:

1、從上圖可以看出,在第二下點擊時,先觸發OnDoubleTap,然后再觸發OnDown(第二次點擊)

2、其次在觸發OnDoubleTap以后,就開始觸發onDoubleTapEvent了,onDoubleTapEvent后面的數字代表了當前的事件,0指ACTION_DOWN,1指ACTION_UP,2 指ACTION_MOVE

在上一個例子的基礎上,我們再添加一個雙擊監聽類,實現如下:public?class?MainActivity?extends?Activity?implements?OnTouchListener{

private?GestureDetector?mGestureDetector;

@Override

protected?void?onCreate(Bundle?savedInstanceState)?{

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mGestureDetector?=?new?GestureDetector(new?gestureListener());?//使用派生自OnGestureListener

mGestureDetector.setOnDoubleTapListener(new?doubleTapListener());

TextView?tv?=?(TextView)findViewById(R.id.tv);

tv.setOnTouchListener(this);

tv.setFocusable(true);

tv.setClickable(true);

tv.setLongClickable(true);

}

/*

*?在onTouch()方法中,我們調用GestureDetector的onTouchEvent()方法,將捕捉到的MotionEvent交給GestureDetector

*?來分析是否有合適的callback函數來處理用戶的手勢

*/

public?boolean?onTouch(View?v,?MotionEvent?event)?{

return?mGestureDetector.onTouchEvent(event);

}

//OnGestureListener監聽

private?class?gestureListener?implements?GestureDetector.OnGestureListener{

public?boolean?onDown(MotionEvent?e)?{

Log.i("MyGesture",?"onDown");

Toast.makeText(MainActivity.this,?"onDown",?Toast.LENGTH_SHORT).show();

return?false;

}

public?void?onShowPress(MotionEvent?e)?{

Log.i("MyGesture",?"onShowPress");

Toast.makeText(MainActivity.this,?"onShowPress",?Toast.LENGTH_SHORT).show();

}

public?boolean?onSingleTapUp(MotionEvent?e)?{

Log.i("MyGesture",?"onSingleTapUp");

Toast.makeText(MainActivity.this,?"onSingleTapUp",?Toast.LENGTH_SHORT).show();

return?true;

}

public?boolean?onScroll(MotionEvent?e1,?MotionEvent?e2,

float?distanceX,?float?distanceY)?{

Log.i("MyGesture22",?"onScroll:"+(e2.getX()-e1.getX())?+"?"+distanceX);

Toast.makeText(MainActivity.this,?"onScroll",?Toast.LENGTH_LONG).show();

return?true;

}

public?void?onLongPress(MotionEvent?e)?{

Log.i("MyGesture",?"onLongPress");

Toast.makeText(MainActivity.this,?"onLongPress",?Toast.LENGTH_LONG).show();

}

public?boolean?onFling(MotionEvent?e1,?MotionEvent?e2,?float?velocityX,

float?velocityY)?{

Log.i("MyGesture",?"onFling");

Toast.makeText(MainActivity.this,?"onFling",?Toast.LENGTH_LONG).show();

return?true;

}

};

//OnDoubleTapListener監聽

private?class?doubleTapListener?implements?GestureDetector.OnDoubleTapListener{

public?boolean?onSingleTapConfirmed(MotionEvent?e)?{

Log.i("MyGesture",?"onSingleTapConfirmed");

Toast.makeText(MainActivity.this,?"onSingleTapConfirmed",?Toast.LENGTH_LONG).show();

return?true;

}

public?boolean?onDoubleTap(MotionEvent?e)?{

Log.i("MyGesture",?"onDoubleTap");

Toast.makeText(MainActivity.this,?"onDoubleTap",?Toast.LENGTH_LONG).show();

return?true;

}

public?boolean?onDoubleTapEvent(MotionEvent?e)?{

Log.i("MyGesture",?"onDoubleTapEvent");

Toast.makeText(MainActivity.this,?"onDoubleTapEvent",?Toast.LENGTH_LONG).show();

return?true;

}

};

}

雙擊一下,部分截圖如下:

34314dbe1c994b05dad0e016174cad25.png

雙擊所對應的觸發事件順序:

40c17e9b6da2ace10e0bc0d1aec060b0.png

輕輕單擊一下,對應的事件觸發順序為:

00ac5ae0c27d8878447d1a2da4f035bd.png

源碼在博客底部給出。

四、GestureDetector.SimpleOnGestureListener---類

它與前兩個不同的是:

1、這是一個類,在它基礎上新建類的話,要用extends派生而不是用implements繼承!

2、OnGestureListener和OnDoubleTapListener接口里的函數都是強制必須重寫的,即使用不到也要重寫出來一個空函數但在SimpleOnGestureListener類的實例或派生類中不必如此,可以根據情況,用到哪個函數就重寫哪個函數,因為SimpleOnGestureListener類本身已經實現了這兩個接口的所有函數,只是里面全是空的而已。

下面利用SimpleOnGestureListener類來重新實現上面的幾個效果,代碼如下:public?class?MainActivity?extends?Activity?implements?OnTouchListener?{

private?GestureDetector?mGestureDetector;

@Override

protected?void?onCreate(Bundle?savedInstanceState)?{

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mGestureDetector?=?new?GestureDetector(new?simpleGestureListener());

TextView?tv?=?(TextView)findViewById(R.id.tv);

tv.setOnTouchListener(this);

tv.setFocusable(true);

tv.setClickable(true);

tv.setLongClickable(true);

}

public?boolean?onTouch(View?v,?MotionEvent?event)?{

//?TODO?Auto-generated?method?stub

return?mGestureDetector.onTouchEvent(event);

}

private?class?simpleGestureListener?extends

GestureDetector.SimpleOnGestureListener?{

/*****OnGestureListener的函數*****/

public?boolean?onDown(MotionEvent?e)?{

Log.i("MyGesture",?"onDown");

Toast.makeText(MainActivity.this,?"onDown",?Toast.LENGTH_SHORT)

.show();

return?false;

}

public?void?onShowPress(MotionEvent?e)?{

Log.i("MyGesture",?"onShowPress");

Toast.makeText(MainActivity.this,?"onShowPress",?Toast.LENGTH_SHORT)

.show();

}

public?boolean?onSingleTapUp(MotionEvent?e)?{

Log.i("MyGesture",?"onSingleTapUp");

Toast.makeText(MainActivity.this,?"onSingleTapUp",

Toast.LENGTH_SHORT).show();

return?true;

}

public?boolean?onScroll(MotionEvent?e1,?MotionEvent?e2,

float?distanceX,?float?distanceY)?{

Log.i("MyGesture",?"onScroll:"?+?(e2.getX()?-?e1.getX())?+?"?"

+?distanceX);

Toast.makeText(MainActivity.this,?"onScroll",?Toast.LENGTH_LONG)

.show();

return?true;

}

public?void?onLongPress(MotionEvent?e)?{

Log.i("MyGesture",?"onLongPress");

Toast.makeText(MainActivity.this,?"onLongPress",?Toast.LENGTH_LONG)

.show();

}

public?boolean?onFling(MotionEvent?e1,?MotionEvent?e2,?float?velocityX,

float?velocityY)?{

Log.i("MyGesture",?"onFling");

Toast.makeText(MainActivity.this,?"onFling",?Toast.LENGTH_LONG)

.show();

return?true;

}

/*****OnDoubleTapListener的函數*****/

public?boolean?onSingleTapConfirmed(MotionEvent?e)?{

Log.i("MyGesture",?"onSingleTapConfirmed");

Toast.makeText(MainActivity.this,?"onSingleTapConfirmed",

Toast.LENGTH_LONG).show();

return?true;

}

public?boolean?onDoubleTap(MotionEvent?e)?{

Log.i("MyGesture",?"onDoubleTap");

Toast.makeText(MainActivity.this,?"onDoubleTap",?Toast.LENGTH_LONG)

.show();

return?true;

}

public?boolean?onDoubleTapEvent(MotionEvent?e)?{

Log.i("MyGesture",?"onDoubleTapEvent");

Toast.makeText(MainActivity.this,?"onDoubleTapEvent",

Toast.LENGTH_LONG).show();

return?true;

}

}

}

到此,有關GestureDetector的所有基礎知識都講解完了,下面給出一個小應用——識別用戶是向左滑還是向右滑!

源碼在博客底部給出。

五、OnFling應用——識別向左滑還是向右滑

這部分就有點意思了,可以說是上面知識的一個小應用,我們利用OnFling函數來識別當前用戶是在向左滑還是向右滑,從而打出日志。先看下OnFling的參數:

boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY)

參數解釋:

e1:第1個ACTION_DOWN MotionEvent

e2:最后一個ACTION_MOVE MotionEvent

velocityX:X軸上的移動速度,像素/秒

velocityY:Y軸上的移動速度,像素/秒

首先,先說一下實現的功能:當用戶向左滑動距離超過100px,且滑動速度超過100 px/s時,即判斷為向左滑動;向右同理.代碼如下:public?class?MainActivity?extends?Activity?implements?OnTouchListener?{

private?GestureDetector?mGestureDetector;

@Override

protected?void?onCreate(Bundle?savedInstanceState)?{

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mGestureDetector?=?new?GestureDetector(new?simpleGestureListener());

TextView?tv?=?(TextView)findViewById(R.id.tv);

tv.setOnTouchListener(this);

tv.setFocusable(true);

tv.setClickable(true);

tv.setLongClickable(true);

}

public?boolean?onTouch(View?v,?MotionEvent?event)?{

//?TODO?Auto-generated?method?stub

return?mGestureDetector.onTouchEvent(event);

}

private?class?simpleGestureListener?extends

GestureDetector.SimpleOnGestureListener?{

/*****OnGestureListener的函數*****/

final?int?FLING_MIN_DISTANCE?=?100,?FLING_MIN_VELOCITY?=?200;

//?觸發條件?:

//?X軸的坐標位移大于FLING_MIN_DISTANCE,且移動速度大于FLING_MIN_VELOCITY個像素/秒

//?參數解釋:

//?e1:第1個ACTION_DOWN?MotionEvent

//?e2:最后一個ACTION_MOVE?MotionEvent

//?velocityX:X軸上的移動速度,像素/秒

//?velocityY:Y軸上的移動速度,像素/秒

public?boolean?onFling(MotionEvent?e1,?MotionEvent?e2,?float?velocityX,

float?velocityY)?{

if?(e1.getX()?-?e2.getX()?>?FLING_MIN_DISTANCE

&&?Math.abs(velocityX)?>?FLING_MIN_VELOCITY)?{

//?Fling?left

Log.i("MyGesture",?"Fling?left");

Toast.makeText(MainActivity.this,?"Fling?Left",?Toast.LENGTH_SHORT).show();

}?else?if?(e2.getX()?-?e1.getX()?>?FLING_MIN_DISTANCE

&&?Math.abs(velocityX)?>?FLING_MIN_VELOCITY)?{

//?Fling?right

Log.i("MyGesture",?"Fling?right");

Toast.makeText(MainActivity.this,?"Fling?Right",?Toast.LENGTH_SHORT).show();

}

return?true;

}

}

}

看完上述內容,你們對如何在Android中利用 GestureDetector進行手勢檢測有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/392056.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/392056.shtml
英文地址,請注明出處:http://en.pswp.cn/news/392056.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Ubuntu2204配置samba

0.前情說明 samba服務器主要是用來局域網共享文件的,如果想公網共享可能行不通,我已經踩坑一天了 所以說如果你想滿足公網samba共享你就可以不要看下去了 1.參考連接 Ubuntu 安裝 Samba 服務器_ubuntu安裝samba服務器-CSDN博客 2.安裝samba服務 sud…

Java—BIO模型

利用 BIO 模型(傳統阻塞 IO 模型)實現多用戶訪問 源代碼 Server類 public class server {public static void main(String[] args) {ExecutorService executorService Executors.newFixedThreadPool(6);try {ServerSocket serverSocketnew ServerSocke…

c++學編程如何鍛煉耐力_我如何學習編程:這是一項耐力運動

c學編程如何鍛煉耐力by Amy M Haddad通過艾米M哈達德(Amy M Haddad) 我如何學習編程:這是一項耐力運動 (How I’m learning to program: it’s an endurance sport) 為什么我的編程學習軌跡反映了我作為跑步者的訓練方式 (Why my learning trajectory for programm…

python處理文本數據

處理文本數據,主要是通過Seris的str訪問。遇到NaN時不做任何處理,保留結果為NaN,遇到數字全部處理為NaN。 str是Seris的方法,DataFrame不能直接使用,但是通過索引選擇DataFrame中的某一行或者某一列,結果為…

Java系列筆記(4) - JVM監控與調優【轉】

Java系列筆記(4) - JVM監控與調優【轉】 目錄 參數設置收集器搭配啟動內存分配監控工具和方法調優方法調優實例 光說不練假把式,學習Java GC機制的目的是為了實用,也就是為了在JVM出現問題時分析原因并解決之。通過學習,我覺得JVM監控與調…

Maven打包排除某個資源或者目錄

最近在spark streaming本地調試的時候&#xff0c;引入了一些資源文件&#xff0c;打包的時候需要給排除掉。所以就考慮使用maven的方式 詳細參考官方文檔&#xff1a;https://maven.apache.org/plugins/maven-jar-plugin/examples/include-exclude.html 排除某個資源文件 <…

android發送網絡請求沒反應,Android無法使用HttpURLConnection發送GET請求

我正在嘗試在我的應用程序中使用HttpURLConnection.我將我的請求方法設置為’GET’,但是當我嘗試檢索輸出流時,該方法將更改為’POST’&#xff01;我不確定是什么原因,但是當我使用’POST’發送請求時,我的JSON服務器(我使用JAX-RS)會返回一個空白頁面.這是我的代碼片段&#…

地圖 c-suite_C-Suite的模型

地圖 c-suiteWe’ve all seen a great picture capture an audience of stakeholders.我們所有人都看到了吸引利益相關者聽眾的美好畫面。 Let’s just all notice that the lady in the front right is not captivated by the image on the board (Photo by Christina wocin…

框架和庫的區別_框架和庫之間的區別

框架和庫的區別Developers often use the terms “library” and “framework” interchangeably. But there is a difference.開發人員經常互換使用術語“庫”和“框架”。 但是有區別。 Both frameworks and libraries are code written by someone else that is used to he…

Java—多線程實現生產者消費者模型

采用線程實現“生產者-消費者”編程的基礎模型 源代碼 消費者代碼&#xff1a; public class Consumer implements Runnable {BlockingQueue<Integer> blockingQueue;int n;CountDownLatch countDownLatch;public Consumer(BlockingQueue<Integer> blockingQueue…

動態鏈接庫.so和靜態鏈接庫.a的區別

靜態鏈接庫&#xff1a; ?擴展名&#xff1a;.a? ?編譯行為&#xff1a;在編譯的時候&#xff0c;將函數庫直接整合到執行程序中&#xff08;所以利用靜態庫編譯生成的文檔會更大&#xff09;??獨立執行的狀態&#xff1a;編譯成功的可執行文件可以獨立運行&#xff0c;不…

華為鴻蒙系統封閉,谷歌正式“除名”華為!“親兒子”榮耀表示:暫不考慮,鴻蒙OS處境尷尬...

我們都知道&#xff0c;目前智能手機最常用操作系統就是IOS和安卓&#xff0c;占據手機系統超過99%的市場份額。由于IOS系統的封閉性&#xff0c;國內手機廠商基本上都是使用谷歌的開源安卓系統。當然華為也不例外&#xff0c;一直使用的都是安卓系統。可以說&#xff0c;安卓系…

使用vue-cli腳手架搭建簡單項目框架

1.首先已經安裝了node,最好版本6以上。 2.安裝淘寶鏡像 大家都知道國內直接使用 npm 的官方鏡像是非常慢的&#xff0c;這里推薦使用淘寶 NPM 鏡像。這樣就可以直接使用cnpm了。 npm install -g cnpm --registryhttps://registry.npm.taobao.org如果過程出差&#xff0c;是否安…

sap中泰國有預扣稅設置嗎_泰國餐廳密度細分:帶有K-means聚類的python

sap中泰國有預扣稅設置嗎Hi! I am Tung, and this is my first stories for my weekend project. What inspired this project is that I have studied to become data scientist for almost two years now mostly from Youtube, coding sites and of course, Medium ,but my l…

自動化yaml文件_從YAML到TypeScript:開發人員對云自動化的看法

自動化yaml文件The rise of managed cloud services, cloud-native, and serverless applications brings both new possibilities and challenges. More and more practices from software development processes like version control, code review, continuous integration,…

SQL SERVER-Extendevent系統視圖

--獲得擴展事件的事件select name,description from sys.dm_xe_objects where object_typeevent order by name--獲得各事件的字段 select c.name,c.description from sys.dm_xe_object_columns c inner join sys.dm_xe_objects o on o.namec.object_name where o.name…

Java—簡單的注冊頁面

根據所提供的界面&#xff0c;編寫 register.html 文件 源代碼 empty.jsp <% page contentType"text/html;charsetUTF-8" language"java" %> <html> <head><title>error</title> </head> <body> <H1><…

【深度學習系列】用PaddlePaddle和Tensorflow實現經典CNN網絡AlexNet

上周我們用PaddlePaddle和Tensorflow實現了圖像分類&#xff0c;分別用自己手寫的一個簡單的CNN網絡simple_cnn和LeNet-5的CNN網絡識別cifar-10數據集。在上周的實驗表現中&#xff0c;經過200次迭代后的LeNet-5的準確率為60%左右&#xff0c;這個結果差強人意&#xff0c;畢竟…

圖片獲取像素坐標html,HTML5畫布Canvas圖片抽取、像素信息獲取、命中檢測

今天主要介紹canvas中比較強大的功能比如將畫布內容抽取為圖片獲取、修改畫布的像素信息以及畫布的命中檢測首先我仍然需要創建畫布圖片抽取首先要明確的一點是toDataURL()是canvas對象自身的方法而不是環境對象的這個方法會將canvas的內容抽取為一張圖片(base64編碼)我們來看一…

CentOS6 下Samba服務器的安裝與配置

原地址&#xff1a;http://www.cnblogs.com/mchina/archive/2012/12/18/2816717.html 一、簡介 Samba是一個能讓Linux系統應用Microsoft網絡通訊協議的軟件&#xff0c;而SMB是Server Message Block的縮寫&#xff0c;即為服務器消息塊 &#xff0c;SMB主要是作為Microsoft的網…