Androidにおけるユーザジェスチャー検出の詳細(OnCliskListener、OnTouchListener、GestureDetecter)

9908 ワード

以前のプロジェクトはただ简単にいくつかのクリックイベントとスライドイベントを応用して、いくつかの细部の便利さはよく分かりませんて、今日わざわざ勉强して、ついでに分かち合って、后の记忆のために
一、クリックイベント:
クリックイベントは簡単で、クリックイベントのリスニングインタフェースをバインドし、クリックイベントのリスニング方法を実現し、onClikメソッドでクリックイベントの処理を行えばよい.イベントリスニングインタフェースOnClickListener、イベントを長押しするリスニングインタフェースOnLongClickListenerなどをクリックします.次に、クリックイベントの簡単な実装手順を示します.
class CliclLister implements OnClickListener{

	@Override
	public void onClick(View v) {
		switch(v.getId()){
		case R.id.but:
			if(v.isPressed()){
				btn.setText("    ");
			}else{
				btn.setText("  ");
			}
			break;
		}
	}
}

Buttonがリスニングイベントをバインドした後、Buttonをクリックしてこのイベントを出発することができ、if(v.idPressed)内部のコードは実行できるが、elseの後ろのコードは実行されず、クリックイベントをキャプチャしたいときに押したり弾いたりするこれらの動作は、この方法では完成しない.クリックイベントの押下と弾き上げを詳しく聞いたらどうしますか?実はとても簡単で、1つの方法は私達がViewをカスタマイズするので、カスタマイズしたViewの中でonTouchEvent方法を書き直してこれらのジェスチャーの傍受を実現して、しかしこの方法はとても愚かで、私達はただユーザーの簡単なジェスチャーを傍受したいだけでまたViewの方法を書き換える必要があります.実はもっと簡単な方法があります.ほほほ.
二、OnTouchListener
最も簡単な方法は、ユーザのジェスチャー操作を傍受するためにOnTouchListenerインターフェースを実装することである.ここで、あるコントロールにOnTouchListenerリスニングを設定した場合、そのView自体の内部のonTouchEventメソッドが実行されるかどうかは、OnTouchListenerインタフェースのonTouchメソッドの戻り値に依存し、戻り値がtrueであれば、View自体の内部のonTouchEventメソッドは呼び出されず、falseが返されるとonTouchEventも正常に呼び出されることに注意してください.これにより、OnTouchListenerのリスニングイベントの優先度はonTouchEventよりも高いことがわかります.
以下、OnTouchListenerの簡単な実装を簡単に見てみましょう.
public class MainActivity extends Activity {
	private Button but;
	private TextView text;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        but = (Button) findViewById(R.id.but);
        text = (TextView) findViewById(R.id.text);
        but.setOnTouchListener(new MyTouchListener());
        but.setOnClickListener(new MyClickListener());
    }
    
    class MyTouchListener implements OnTouchListener{

		@Override
		public boolean onTouch(View v, MotionEvent event) {
			switch (event.getAction()) {
			case KeyEvent.ACTION_DOWN:
				but.setText("      "); 
				break;
			case KeyEvent.ACTION_UP:
				but.setText("     "); 
				break;

			default:
				break;
			}
			return true;
		}
    }
    
    class MyClickListener implements OnClickListener{

		@Override
		public void onClick(View v) {
			if(v.getId() == R.id.but){
				text.setText("          !!");
				text.setTextColor(Color.RED);
			}
		}
    	
    }
}

コードは簡単で、Buttonは2つのリスニングをバインドして、1つはOnTouchListenerで、1つはOnClickListenerで、私たちはこのボタンをクリックして発見して、OnTouchListenerのリスニング方法は実行して、OnClickListenerのリスニング方法は実行していません.
実際には、OnTouchListenerのonTouchメソッドの戻り値はtrueです.これは、イベントが内部でのみ処理され、ViewのonTouchEventに渡されないことを示しています.OnClickListenerの実行プロセスは、onTouchEventの後であり、onTouchEventメソッドで現在のViewがOnClickListenerを設定していることを発見したら、onClickイベントを処理し、イベント処理の優先度を得ることができます.
OnTouchListener -> onTouchEvent -> OnClickListener
三、GestureDetectorが強気に襲いかかる
ユーザーが画面に触れると、down、up、scroll、filingなど、多くのジェスチャーが発生します.彼のonTouch(Viewv,MotionEvent event)メソッドを書き換えることで、touchイベントを処理することができますが、このメソッドは簡単すぎて、複雑なジェスチャーを処理する必要がある場合は、このインタフェースを使うのは面倒です(ユーザーが触った軌跡に基づいてジェスチャーを判断する必要があるからです).Android sdkはGestureDetector(Gesture:ジェスチャーDetector:識別)クラスを提供してくれて、このクラスを通じて多くのジェスチャーを識別することができます.GestureDetectorはジェスチャーを扱うことができるが,異なるジェスチャーの処理はプログラマーに自分で処理させることである.
GestureDetectorクラスには、2つのインタフェースと1つの内部クラスがあります.
インタフェース:OnGestureListener,OnDoubleTapListener内部クラス:SimpleOnGestureListener
次に、OnGestureListenerインタフェースを見てみましょう.
(1)GestureDetector.OnGestureListener---インタフェース
class MyGestureDetector implements OnGestureListener{

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

		@Override
		public void onShowPress(MotionEvent e) {
			//             ,                  ,  onShowPress    ,         
			
		}

		@Override
		public boolean onSingleTapUp(MotionEvent e) {
			//            ,         ,     ,       ,  ,    Down        ,      Single   ,            
			return false;
		}

		@Override
		public boolean onScroll(MotionEvent e1, MotionEvent e2,
				float distanceX, float distanceY) {
			//         。       view,          ,      ,    
			return false;
		}

		@Override
		public void onLongPress(MotionEvent e) {
			//        
			
		}

		@Override
		public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
				float velocityY) {
			//   ,       、       , 1 MotionEvent ACTION_DOWN,   ACTION_MOVE, 1 ACTION_UP  
			return false;
		}
    	
    }

GestureDetectorを作成するには、次の3つのセクションが必要です.
1.コンストラクションインスタンスを使用するか、コンストラクションクラスを使用するか、OnGestureListenerリスニング関数を作成します.OnGestureListener=newOnGestureListener()またはclass MyGestureListener implements OnGestureListener{
}
2.GestureDetectorインスタンスgestureDetectorを作成します.コンストラクション関数は3つあります.必要に応じて選択できます.
    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.OnTouchListenerのonTouchメソッドでイベントをブロックする
public boolean onTouch(View v, MotionEvent event) {  
        return gestureDetector.onTouchEvent(event);     
    }

4.コントロールバインドリスニング
TextView tv = (TextView)findViewById(R.id.tv);  
tv.setOnTouchListener(this); 

簡単な実装を見てみましょう
まず、メインレイアウトページにtextViewを追加し、その上のジェスチャー認識を容易にし、textViewを比較的大きく配置し、ユーザーのジェスチャーリスニングがtextviewで表示され、ジェスチャーリスニングのプロセスを表示しやすくし、レイアウトファイルコードは以下の通りである.


    
    
    
    
下面是Java代码,代码中监听在TextView上的手势,并且将手势的监听过程打印在TextView上,具体代码如下:

public class ActivityOnGestureOne extends Activity implements OnTouchListener{
	private TextView text;
	private Button but;
	GestureDetector myGestureDetector;
	@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.ongesture_listener);
        init();
	}
	private void init() {
		text = (TextView) findViewById(R.id.text);
		but = (Button) findViewById(R.id.but);
		myGestureDetector = new GestureDetector(new MyGestureListener()); //     OnGestureListener  
		text.setOnTouchListener(this);
		text.setFocusable(true);     
		text.setClickable(true);     
		text.setLongClickable(true);
		but.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				text.setText("");
			}
		});
	}
	
	//     MotionEvent  GestureDetector
	@Override
	public boolean onTouch(View v, MotionEvent event) {
		return myGestureDetector.onTouchEvent(event); 
	}
	
	class MyGestureListener implements OnGestureListener{

		//        , 1 MotionEvent ACTION_DOWN    
		@Override
		public boolean onDown(MotionEvent e) {
			text.append("  onDown  ");
			Log.i("MyGesture", "onDown"); 
			return false;
		}

		/*   
         *        ,       ,   1 MotionEvent ACTION_DOWN     
         *    onDown()   ,                  
         *  
         *  onDown     MotionEventACTION_DOWN   ,         , 
         *             ,  MotionEventACTION_DOWN,onDown    , 
         *                     onShowPress    ,             
         * (                 ,         onShowPress)   ,    onShowPress。 
         */ 
		@Override
		public void onShowPress(MotionEvent e) {
			text.append("  onShowPress  ");
			Log.i("MyGesture", "onShowPress"); 
		}

		 /*  (      )  ,   1 MotionEvent ACTION_UP       
        	      ,     ,         
        	        ,           ,  ,    Down        ,      Single   ,              */
		@Override
		public boolean onSingleTapUp(MotionEvent e) {
			text.append("  onSingleTapUp  ");
			Log.i("MyGesture", "onSingleTapUp"); 
			return true;
		}

		//        ,   , 1 MotionEvent ACTION_DOWN,   ACTION_MOVE    
		@Override
		public boolean onScroll(MotionEvent e1, MotionEvent e2,
				float distanceX, float distanceY) {
			text.append("  onScroll  ");
			Log.i("MyGesture", "onScroll"); 
			return true;
		}

		//            
		@Override
		public void onLongPress(MotionEvent e) {
			text.append("  onLongPress  ");
			Log.i("MyGesture", "onLongPress"); 
			
		}

		//        、       , 1 MotionEvent ACTION_DOWN,   ACTION_MOVE, 1 ACTION_UP    
		@Override
		public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
				float velocityY) {
			text.append("  onFling  ");
			Log.i("MyGesture", "onFling"); 
			return true;
		}
		
	}
}
読者は自分でジェスチャーで傍受する印刷を通じて自分で傍受過程を分析することができ、以下は私が切り取ったTextViewをクリックしてスライドするスクリーンショットです.
(2)GestureDetector.OnDoubleTapListener---インタフェース