Android 手势操作GestureDetector
在很多應(yīng)用中我們經(jīng)常會(huì)看到一些不同手勢(shì)的點(diǎn)擊事件,例如QQ的消息列表,我們可以通過(guò)左滑消息來(lái)選擇刪除或者置頂或者標(biāo)記為已讀,我們也可以通過(guò)右滑拖出QQ菜單。有些應(yīng)用中還會(huì)有長(zhǎng)按,雙擊等手勢(shì)。但是一般情況下,這些操作的手勢(shì)都不是很復(fù)雜,不會(huì)出現(xiàn)什么右擊左擊,或者三連擊這樣的手勢(shì)。因?yàn)殚_(kāi)發(fā)應(yīng)用的原則就是簡(jiǎn)單化,讓別人可以一看就懂,一看就會(huì)。
今天我們就來(lái)學(xué)習(xí)一下Android中手勢(shì)的操作。在Android中手勢(shì)的操作使用GestureDetector這個(gè)類。
GestureDetector概述
Detects various gestures and events using the supplied MotionEvents. The GestureDetector.OnGestureListener callback will notify users when a particular motion event has occurred. This class should only be used with MotionEvents reported via touch (don’t use for trackball events).
GestureDetector通過(guò)MotionEvent類檢測(cè)不同的手勢(shì)和事件。在MotionEvent有很多基礎(chǔ)的動(dòng)作監(jiān)測(cè):ACTION_CANCEL(動(dòng)作取消), ACTION_DOWN(按下), ACTION_MOVE(移動(dòng)),ACTION_UP(抬起)等,而手勢(shì)的操作就是以MotionEvent中這些基本的動(dòng)作為基礎(chǔ)的,通過(guò)將這些基本的動(dòng)作組合從而形成手勢(shì)。在GestureDetector中有一個(gè)GestureDetector.OnGestureListener監(jiān)聽(tīng)類,這個(gè)類都是當(dāng)手勢(shì)發(fā)生時(shí)調(diào)用的。
要使用GestureDetector類,我們首先要?jiǎng)?chuàng)建它的對(duì)象,我們先來(lái)看他的構(gòu)造器:
注意:GestureDetector(GestureDetector.OnGestureListener listener, Handler handler)和GestureDetector(GestureDetector.OnGestureListener listener)在API level 3以后已經(jīng)取代,這里不再列出。
- GestureDetector(Context context, GestureDetector.OnGestureListener listener)
傳入兩個(gè)參數(shù),一個(gè)是Context的對(duì)象,一個(gè)是GestureDetector.OnGestureListener的對(duì)象。上面已經(jīng)講過(guò)GestureDetector.OnGestureListener是什么。 - GestureDetector(Context context, GestureDetector.OnGestureListener listener, Handler handler)
前兩個(gè)不用說(shuō)了,第三個(gè)我查了一下API,原文是這樣:”the handler to use for running deferred listener events.”,意思應(yīng)該是當(dāng)運(yùn)行延時(shí)的監(jiān)聽(tīng)對(duì)象時(shí)使用這個(gè)Handler對(duì)象。 - GestureDetector(Context context, GestureDetector.OnGestureListener listener, Handler handler, boolean unused)
前三個(gè)不用說(shuō)了吧,最后一個(gè)是定義當(dāng)前有沒(méi)有被使用。
一般情況下我們都是使用第一個(gè)構(gòu)造器。
GestureDetector中的方法不是很多,有兩個(gè)是非常重要的,我們這里拿出來(lái)說(shuō)一說(shuō),其他的看名字就了解如何使用了: - onGenericMotionEvent(MotionEvent ev)
當(dāng)我們的手勢(shì)動(dòng)作是由GenericMotionEvent動(dòng)作構(gòu)成時(shí),我們需要調(diào)用這個(gè)方法,這樣我們定義的手勢(shì)才可用。 onTouchEvent(MotionEvent ev)
當(dāng)我們的手勢(shì)是由MotionEvent 構(gòu)成時(shí),我們需要調(diào)用這個(gè)方法,手勢(shì)才能生效。我們下面來(lái)看一下GestureDetector手勢(shì)是如何定義的?
GestureDetector.SimpleOnGestureListener
創(chuàng)建手勢(shì),首先要?jiǎng)?chuàng)建一個(gè)GestureDetector對(duì)象。創(chuàng)建GestureDetector對(duì)象時(shí)要傳入一個(gè)GestureDetector.OnGestureListener對(duì)象,所以我們要?jiǎng)?chuàng)建一個(gè)GestureDetector.OnGestureListener對(duì)象,但是GestureDetector.OnGestureListener是一個(gè)interface接口,有人可能會(huì)想我們可以創(chuàng)建一個(gè)GestureDetector.OnGestureListener的匿名內(nèi)部類啊,這樣是可以,但是要實(shí)現(xiàn)GestureDetector.OnGestureListener中的好多方法,這樣會(huì)使我們代碼冗長(zhǎng)復(fù)雜。API中給我們提供了一個(gè)解決的方法,就是通過(guò)使用GestureDetector.SimpleOnGestureListener類。
我們看API中對(duì)他的描述:A convenience class to extend when you only want to listen for a subset of all the gestures. This implements all methods in the GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener, and GestureDetector.OnContextClickListener but does nothing and return false for all applicable methods.
大體意思是這樣的:我們可以通過(guò)使用這個(gè)類來(lái)監(jiān)聽(tīng)一系列的手勢(shì)操作,也就是我們可以使用這二個(gè)監(jiān)聽(tīng)器監(jiān)聽(tīng)多個(gè)手勢(shì),這個(gè)類繼承了: GestureDetector.OnGestureListener(手勢(shì)監(jiān)聽(tīng)器), GestureDetector.OnDoubleTapListener(雙擊監(jiān)聽(tīng)器), and GestureDetector.OnContextClickListener(上下文點(diǎn)擊監(jiān)聽(tīng)器)中的所有方法。
我們來(lái)看一下他的方法:
onContextClick(MotionEvent e):上下文點(diǎn)擊手勢(shì)。
onDoubleTap(MotionEvent e):雙擊手勢(shì)。
onDoubleTapEvent(MotionEvent e):雙擊按下和抬起分別產(chǎn)生點(diǎn)擊事件手勢(shì)。
onDown(MotionEvent e):單擊手勢(shì)。
onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY):滑動(dòng)手勢(shì),這個(gè)要與onScroll區(qū)別:onFling是滑動(dòng)后,事件響應(yīng);onScroll是手指滑動(dòng)時(shí),控件也跟著滑動(dòng),同時(shí)響應(yīng)。
onLongPress(MotionEvent e):長(zhǎng)按手勢(shì)。
onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY):拖動(dòng)手勢(shì)。
onShowPress(MotionEvent e):按下時(shí)響應(yīng)事件。
onSingleTapConfirmed(MotionEvent e):單擊手勢(shì)。
onSingleTapUp(MotionEvent e):也是單擊手勢(shì),是單擊抬起后響應(yīng)時(shí)間。
手勢(shì)定義
前面基礎(chǔ)差不多都打好了,下面我們來(lái)使用下。這里只練習(xí):雙擊,滑動(dòng)和拖動(dòng)的手勢(shì)操作。
手勢(shì)定義 ###
定義一個(gè)MyButton類繼承Button控件。
public class MyButton extends Button {private GestureDetector mGestureDetector;//定義手勢(shì)對(duì)象//自定義View的構(gòu)造器public MyButton(Context context) {super(context);}public MyButton(Context context, AttributeSet attrs) {super(context, attrs);//初始化GestureDetector對(duì)象,傳入GestureDetector.SimpleOnGestureListener對(duì)象,監(jiān)聽(tīng)多個(gè)手勢(shì)。mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {//監(jiān)聽(tīng)雙擊手勢(shì)@Overridepublic boolean onDoubleTap(MotionEvent e) { Log.d("data", "點(diǎn)擊了兩次按鈕! ");return true;}//監(jiān)聽(tīng)滑動(dòng)手勢(shì)@Overridepublic boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {if (Math.abs(e2.getX() - e1.getX()) > 0) {//設(shè)置控件滑動(dòng)的動(dòng)畫ObjectAnimator.ofFloat(MyButton.this, "translationX", getTranslationX(), getTranslationX() + (e2.getX() - e1.getX())).setDuration(500).start();return true;}return super.onFling(e1, e2, velocityX, velocityY);}//監(jiān)聽(tīng)拖動(dòng)的手勢(shì)@Overridepublic boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {//設(shè)置控件跟隨手勢(shì)移動(dòng)setTranslationY(getTranslationY() + e2.getY() - e1.getY());setTranslationX(getTranslationX() + e2.getX() - e1.getX());return true;}});}@Overridepublic boolean onTouchEvent(MotionEvent event) {//調(diào)用此方法,實(shí)現(xiàn)手勢(shì)的監(jiān)聽(tīng)使用。mGestureDetector.onTouchEvent(event);return super.onTouchEvent(event);} } 注意:復(fù)制代碼使用時(shí),onFling方法和onScroll方法不要同時(shí)使用,因?yàn)樾Ч?#xff0c;可能會(huì)看不出效果來(lái)。使用onFling手勢(shì)將onScroll方法屏蔽掉,使用onScroll手勢(shì)時(shí)同理。
雙擊手勢(shì):
滑動(dòng)手勢(shì):
拖動(dòng)手勢(shì):
Activity中響應(yīng)手勢(shì)事件
如果我們想在Activity中使用雙擊,滑動(dòng),拖動(dòng)的點(diǎn)擊事件,我們需要在MyButton中定義一個(gè)點(diǎn)擊事件。這里我們以雙擊為例,在MyButton中添加如下代碼:(這里使用到了自定義View中的自定義點(diǎn)擊事件知識(shí)點(diǎn),不懂的可以查看《Android 自定義View——自定義點(diǎn)擊事件 》這篇博客。)
//這里其實(shí)是使用的自定義View的點(diǎn)擊事件public OnDoubleClickListerner onDoubleClickListerner;//定義雙擊的監(jiān)聽(tīng)接口對(duì)象//設(shè)置獲得雙擊的監(jiān)聽(tīng)接口對(duì)象的set方法。public void setOnDoubleClickListerner(OnDoubleClickListerner onDoubleClickListerner) {this.onDoubleClickListerner = onDoubleClickListerner;}//創(chuàng)建雙擊的監(jiān)聽(tīng)接口interface OnDoubleClickListerner {void onDoubleClick(View view);}在雙擊手勢(shì)中添加:
//監(jiān)聽(tīng)雙擊手勢(shì)@Overridepublic boolean onDoubleTap(MotionEvent e) {if (onDoubleClickListerner != null) {onDoubleClickListerner.onDoubleClick(MyButton.this);}Log.d("data", "點(diǎn)擊了兩次按鈕! ");return true;}這樣我們就可以在Activity中使用了:
public class MainActivity extends AppCompatActivity {private MyButton button;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);button = (MyButton) findViewById(R.id.button);button.setOnDoubleClickListerner(new MyButton.OnDoubleClickListerner() {@Overridepublic void onDoubleClick(View view) {Log.d("data", "點(diǎn)擊了兩次按鈕! ");//次此處添加處理代碼}});} }總結(jié)
以上是生活随笔為你收集整理的Android 手势操作GestureDetector的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 3月9日—3月13日四年级课程表
- 下一篇: 快速寻找9位数内的自幂数