編輯:關於Android編程
一般情況下,我們知道View類有個View.OnTouchListener內部接口,通過重寫他的onTouch(View v, MotionEvent event)方法,我們可以處理一些touch事件,但是這個方法太過簡單,如果需要處理一些復雜的手勢,用這個接口就會很麻煩(因為我們要自己根據用戶觸摸的軌跡去判斷是什麼手勢)。
Android sdk給我們提供了GestureDetector(Gesture:手勢Detector:識別)類,通過這個類我們可以識別很多的手勢,主要是通過他的onTouchEvent(event)方法完成了不同手勢的識別。雖然他能識別手勢,但是不同的手勢要怎麼處理,應該是提供給程序員實現的。
GestureDetector這個類對外提供了兩個接口:OnGestureListener,OnDoubleTapListener,還有一個內部類SimpleOnGestureListener。
GestureDetector.OnDoubleTapListener接口:用來通知DoubleTap事件,類似於鼠標的雙擊事件。
1,onDoubleTap(MotionEvent e):在雙擊的第二下,Touch down時觸發 。
2,onDoubleTapEvent(MotionEvent e):通知DoubleTap手勢中的事件,包含down、up和move事件(這裡指的是在雙擊之間發生的事件,例如在同一個地方雙擊會產生DoubleTap手勢,而在DoubleTap手勢裡面還會發生down和up事件,這兩個事件由該函數通知);雙擊的第二下Touch down和up都會觸發,可用e.getAction()區分。
3,onSingleTapConfirmed(MotionEvent e):用來判定該次點擊是SingleTap而不是DoubleTap,如果連續點擊兩次就是DoubleTap手勢,如果只點擊一次,系統等待一段時間後沒有收到第二次點擊則判定該次點擊為SingleTap而不是DoubleTap,然後觸發SingleTapConfirmed事件。這個方法不同於onSingleTapUp,他是在GestureDetector確信用戶在第一次觸摸屏幕後,沒有緊跟著第二次觸摸屏幕,也就是不是“雙擊”的時候觸發
GestureDetector.OnGestureListener接口:用來通知普通的手勢事件,該接口有如下六個回調函數:
1. onDown(MotionEvent e):down事件;
2. onSingleTapUp(MotionEvent e):一次點擊up事件;在touch down後又沒有滑動
(onScroll),又沒有長按(onLongPress),然後Touchup時觸發。
點擊一下非常快的(不滑動)Touchup:
onDown->onSingleTapUp->onSingleTapConfirmed
點擊一下稍微慢點的(不滑動)Touchup:
onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed
3. onShowPress(MotionEvent e):down事件發生而move或則up還沒發生前觸發該
事件;Touch了還沒有滑動時觸發(與onDown,onLongPress)比較onDown只要Touch down一定立刻觸發。而Touchdown後過一會沒有滑動先觸發onShowPress再是onLongPress。所以Touchdown後一直不滑動
按照onDown->onShowPress->onLongPress這個順序觸發。
4. onLongPress(MotionEvent e):長按事件;Touch了不移動一直Touch down時觸發;
5. onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY):滑動手
勢事件;Touch了滑動一點距離後,在ACTION_UP時才會觸發 ;
參數:e1 第1個ACTION_DOWN MotionEvent 並且只有一個;e2 最後一個ACTION_MOVE MotionEvent ;velocityX X軸上的移動速度,像素/秒 ;velocityY Y軸上的移動速度,像素/秒.觸發條件:X軸的坐標位移大於FLING_MIN_DISTANCE,且移動速度大於FLING_MIN_VELOCITY個像素/秒
6. onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY):在屏幕上
拖動事件。無論是用手拖動view,或者是以拋的動作滾動,都會多次觸發,這個方法在ACTION_MOVE動作發生時就會觸發。
點擊一下非常快的(不滑動)Touchup:
onDown->onSingleTapUp->onSingleTapConfirmed
點擊一下稍微慢點的(不滑動)Touchup:
onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed
自定義Button控件,實現手勢的監聽和處理:
public class MyButton extends Button {
private GestureDetector mGesture;
private OnDoubleClickListener onDoubleClickListener;
//自定義監聽器接口
interface OnDoubleClickListener{
void onDoubleClick(View view);
}
//設置雙擊事件監聽器的方法
public void setOnDoubleClickListener(OnDoubleClickListener onDoubleClickListener){
this.onDoubleClickListener = onDoubleClickListener;
};
public MyButton(Context context) {
super(context);
}
public MyButton(final Context context, AttributeSet attrs) {
super(context, attrs);
//
mGesture = new GestureDetector(context,new GestureDetector.SimpleOnGestureListener(){
@Override
public boolean onDoubleTap(MotionEvent e) {
if(onDoubleClickListener!=null) {
onDoubleClickListener.onDoubleClick(MyButton.this);
}
Toast.makeText(context,雙擊事件,Toast.LENGTH_SHORT).show();
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
/**
* 滑動和拖拽最好不要一起實現,會產生矛盾
*/
if(Math.abs(e1.getX()-e2.getX())>50){
setTranslationX(e2.getX() - e1.getX());
//根據手勢滑動的距離而在水平方向上滑動控件
ObjectAnimator.ofFloat(MyButton.this,translationX,getTranslationX(),e2.getX()-e1.getX())
.setDuration(500).start();
return true;
}
return super.onFling(e1, e2, velocityX, velocityY);
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
//根據手勢拖拽控件的相位而移動控件
setTranslationX(getTranslationX()+e2.getX() - e1.getX());
setTranslationY(getTranslationX()+e2.getY() - e1.getY());
return super.onScroll(e1, e2, distanceX, distanceY);
}
});
}
public MyButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
if(event.getAction()==MotionEvent.ACTION_DOWN){
}
return super.dispatchTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
//touch事件傳給onTouchEvent()
mGesture.onTouchEvent(event);
return super.onTouchEvent(event);
}
}
布局:
主活動:
public class MainActivity extends Activity {
private MyButton myButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myButton = (MyButton) findViewById(R.id.button_doubleTap);
myButton.setOnDoubleClickListener(new MyButton.OnDoubleClickListener() {
@Override
public void onDoubleClick(View view) {
Log.d(,點擊兩次);
}
});
}
}
結果演示:
雙擊:
滑動:<喎?/kf/ware/vc/" target="_blank" class="keylink">vc3Ryb25nPjxiciAvPg0KPGltZyBhbHQ9"這裡寫圖片描述" src="/uploadfile/Collfiles/20150928/2015092808542559.gif" title="\" />
拖拽:
顧名思義,AndroidEventBus ( github鏈接 : https://github.com/bboyfeiyu/AndroidEventBus
本文主要介紹Android4.4默認Home應用Launcher3的啟動過程和Launcher3的數據加載過程。Launcher的啟動是開機時,ActivityManag
0. 前言今天這篇文章主要描述二維碼的生成與掃描,使用目前流行的Zxing,為什麼要講二維碼,因為二維碼太普遍了,隨便一個Android APP都會有二維碼掃描。本篇旨在
自從開始負責公共控件模塊開始,我一直都想好好分析一下Android事件傳遞流程,相信網上有一大堆相關文章,但是我個人覺得作為一個專業的控件開發人員,如果只是知道一下大概,