天天看點

Android之手勢互動的詳解

手勢:是指使用者手指或者觸摸筆在觸摸屏上連續觸碰的一種行為

使用手勢檢測需要倆個步驟:

1.建立一個GestureDetector對象,識别各種手勢

2.為應用程式的activity的TouchEvent事件綁定事件監聽器,在事件進行中指定把activity上的touchEvent的事件交給GestureDetector處理

代碼如下:

//1.建立一個GestureDetector對象,識别各種手勢
	private GestureDetector mGestureDetector;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		mGestureDetector=new GestureDetector(this, this);
	}
	
	//2.在事件進行中指定把activity上的touchEvent的事件交給GestureDetector處理
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
		return mGestureDetector.onTouchEvent(event);
	}
	
           

識别手勢有6個方法~

分别為onDown,onShowPress,onSingleTapUp,onScroll,onLongPress,onFling

讓Activity實作OnGestureListener接口,這就要重寫這6個方法~

詳細解釋如下:

//按下:剛剛手指接觸到觸摸屏的那一刹那
	@Override
	public boolean onDown(MotionEvent e) {
		// TODO Auto-generated method stub
		System.out.println("onDown");
		return false;
	}
	//按住:手指按在觸摸屏上,它的時間範圍在按下起效,在長按之前
	@Override
	public void onShowPress(MotionEvent e) {
		// TODO Auto-generated method stub
		System.out.println("onShowPress");
		
	}
	//擡起:手指離開觸摸屏的那一刹那,
	@Override
	public boolean onSingleTapUp(MotionEvent e) {
		// TODO Auto-generated method stub
		System.out.println("onSingleTapUp");
		return false;
	}
	//滑動
	@Override
	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
		// TODO Auto-generated method stub
		System.out.println("onScroll");
		return false;
	}
	//長按,手指按住持續一段時間,并且沒有松開
	@Override
	public void onLongPress(MotionEvent e) {
		// TODO Auto-generated method stub
		System.out.println("onLongPress");
		
	}
	//抛擲:快速滑動的時候執行這個方法,并且松開的動作
	@Override
	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
		// TODO Auto-generated method stub
		System.out.println("onFling");
		return false;
	}
           

狀态不同的時候要調用哪個方法呢???如下:

點選:onDown-onSingleTapup

長按并且未擡起:onDown--onShowPress--onLongPress

長按(按了一段時間就擡起了):onDown--onShowPress--onSingleTapup

迅速滑動:onDown--onScroll....--onFling

緩慢滑動:onDown--onScroll.....

MainActivity全部代碼:

public class MainActivity extends Activity implements OnGestureListener{

	//1.建立一個GestureDetector對象,識别各種手勢
	private GestureDetector mGestureDetector;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		mGestureDetector=new GestureDetector(this, this);
	}
	
	//2.在事件進行中指定把activity上的touchEvent的事件交給GestureDetector處理
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
		return mGestureDetector.onTouchEvent(event);
	}
	
	
	//按下:剛剛手指接觸到觸摸屏的那一刹那
	@Override
	public boolean onDown(MotionEvent e) {
		// TODO Auto-generated method stub
		System.out.println("onDown");
		return false;
	}
	//按住:手指按在觸摸屏上,它的時間範圍在按下起效,在長按之前
	@Override
	public void onShowPress(MotionEvent e) {
		// TODO Auto-generated method stub
		System.out.println("onShowPress");
		
	}
	//擡起:手指離開觸摸屏的那一刹那,
	@Override
	public boolean onSingleTapUp(MotionEvent e) {
		// TODO Auto-generated method stub
		System.out.println("onSingleTapUp");
		return false;
	}
	//滑動
	@Override
	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
		// TODO Auto-generated method stub
		System.out.println("onScroll");
		return false;
	}
	//長按,手指按住持續一段時間,并且沒有松開
	@Override
	public void onLongPress(MotionEvent e) {
		// TODO Auto-generated method stub
		System.out.println("onLongPress");
	}
	//抛擲:快速滑動的時候執行這個方法,并且松開的動作
	@Override
	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
		// TODO Auto-generated method stub
		System.out.println("onFling");
		return false;
	}
}
           

效果圖:

Android之手勢互動的詳解

現在再實作另外一個功能~

長按跳轉到電子翻書效果的一個界面~

隻需要在onLongPress方法中添加幾行代碼就行了~

//長按,手指按住持續一段時間,并且沒有松開
	@Override
	public void onLongPress(MotionEvent e) {
		// TODO Auto-generated method stub
		System.out.println("onLongPress");
		Intent intent=new Intent(this,SecondActivity.class);
		startActivity(intent);
	}
           

在SecondActivity的這個界面中,實作了電子翻書的效果-動畫左右滑動效果

其實也就是使用了補件動畫的知識~

還使用ViewFlipper實作了動畫的左右滑動效果

步驟如下:

在res檔案下建立anim檔案

在anim檔案夾下面建立了4個xml檔案,分别是next_in,next_off,pre_in,pre_off,分别代表的意思是下一張圖檔向左進來,這一張圖檔向左出去,上一張圖檔向右進來,這一張圖檔向右出去

代碼如下:

next_in:

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fromXDelta="100%p"
    android:fromYDelta="0"
    android:toXDelta="0"
    android:toYDelta="0">
    
</translate>
           

next_off:

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fromXDelta="0"
    android:fromYDelta="0"
    android:toXDelta="-100%p"
    android:toYDelta="0">
    

</translate>
           

pre_in:

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fromXDelta="-100%p"
    android:fromYDelta="0"
    android:toXDelta="0"
    android:toYDelta="0">
    

</translate>
           

pre_off:

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fromXDelta="0"
    android:fromYDelta="0"
    android:toXDelta="100%p"
    android:toYDelta="0">
</translate>
           

MainActivity:

public class SecondActivity extends Activity implements OnGestureListener{

	//電子翻書動作
	
	private ViewFlipper mViewFlipper;
	private GestureDetector mGestureDetector;
	private Animation[] animations=new Animation[4];
	
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_second);
		animations[0]=AnimationUtils.loadAnimation(this, R.anim.next_in);
		animations[1]=AnimationUtils.loadAnimation(this, R.anim.next_off);
		animations[2]=AnimationUtils.loadAnimation(this, R.anim.pre_in);
		animations[3]=AnimationUtils.loadAnimation(this, R.anim.pre_off);
		mGestureDetector=new GestureDetector(this, this);
		mViewFlipper=(ViewFlipper) findViewById(R.id.vf);
		mViewFlipper.addView(getImageView(R.drawable.a1));
		mViewFlipper.addView(getImageView(R.drawable.a2));
		mViewFlipper.addView(getImageView(R.drawable.a3));
	}

	private ImageView getImageView(int resId){
		ImageView imageView=new ImageView(this);
		imageView.setImageResource(resId);
		return imageView;
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
		return mGestureDetector.onTouchEvent(event);
	}
	@Override
	public boolean onDown(MotionEvent e) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void onShowPress(MotionEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public boolean onSingleTapUp(MotionEvent e) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void onLongPress(MotionEvent e) {
		// TODO Auto-generated method stub
	}

	
	/*
	 *第一個參數:按下的觸點
	 *第二個參數:擡起的觸點
	 *第三個參數:在x軸的滑動速度
	 *第四個:在y軸的滑動速度
	 */
	@Override
	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
		// TODO Auto-generated method stub
		//50是誤內插補點
		if(e2.getX()-e1.getX()>50){
			//從左向右滑
			//這一頁向右出去
			mViewFlipper.setOutAnimation(animations[3]);
			//上一頁進來
			mViewFlipper.setInAnimation(animations[2]);
			mViewFlipper.showPrevious();
		}else if(e1.getX()-e2.getX()>50){
			//從右向左滑
			//這一頁向左出去
			mViewFlipper.setOutAnimation(animations[1]);
			//下一頁向左進來
			mViewFlipper.setInAnimation(animations[0]);
			mViewFlipper.showNext();
		}
		return false;
	}
}
           

效果圖如下:

Android之手勢互動的詳解

現在在實作另外一個功能~倆點的觸摸使圖檔變大變小

這個是要到真機上測試的~

一樣在SecondActivity中的onLongPress方法中添加跳轉到ThirdActivity的代碼,這裡我就不寫了~

在ThirdActivity中,通過手指的距離來控制圖檔的大小

我就不詳細說了,代碼如下:

public class ThirdACtivity extends Activity implements OnGestureListener{

	private ImageView image;
	private GestureDetector mGestureDetector;
	private float lastCurrent=-1f;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_third_activity);
		image=(ImageView) findViewById(R.id.image);
		mGestureDetector=new GestureDetector(this, this);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
		return mGestureDetector.onTouchEvent(event);
	}
	
	@Override
	public boolean onDown(MotionEvent e) {
		// TODO Auto-generated method stub
		lastCurrent=-1f;
		return false;
	}

	@Override
	public void onShowPress(MotionEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public boolean onSingleTapUp(MotionEvent e) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
		// TODO Auto-generated method stub
		if (e2.getPointerCount()==2) {
			float x=e2.getX(0)-e2.getX(1);
			float y=e2.getY(0)-e2.getY(1);
			float current=(float) Math.sqrt(x*x+y*y);
			if(lastCurrent<0){
				lastCurrent=current;
			}else{
				RelativeLayout.LayoutParams params=(RelativeLayout.LayoutParams) image.getLayoutParams();
			if (lastCurrent-current>2) {
				//倆點距離變小
				System.out.println("縮小");
				lastCurrent=current;
				//縮小
				params.width=(int) (0.9*image.getWidth());
				params.height=(int) (0.9*image.getHeight());
				//縮小最小到100
				if(params.width>100){
					image.setLayoutParams(params);
				}
			} else if(current-lastCurrent>2){
				//倆點距離變大
               System.out.println("放大");
               lastCurrent=current;
             //放大
				params.width=(int) (1.1*image.getWidth());
				params.height=(int) (1.1*image.getHeight());
				//放大最大到1000
				if(params.width<1000){
					image.setLayoutParams(params);
				}
			}
			}
		} 
		return true;
	}

	@Override
	public void onLongPress(MotionEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
		// TODO Auto-generated method stub
		return false;
	}

	
}
           

效果圖不好貼~我就不貼了

源碼:http://download.csdn.net/detail/qq_33642117/9585069