Android GestureDetector手势识别类

为了加强鼠标响应事件,Android提供了GestureDetector手势识别类。通过GestureDetector.OnGestureListener来获取当前被触发的操作手势(Single Tap Up、Show Press、Long Press、Scroll、Down、Fling),具体包括以下几种:

boolean  onDoubleTap(MotionEvent e) 
解释:双击的第二下Touch down时触发 
boolean  onDoubleTapEvent(MotionEvent e) 
解释:双击的第二下Touch down和up都会触发,可用e.getAction()区分。 
boolean  onDown(MotionEvent e) 
解释:Touch down时触发 
boolean  onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) 
解释:Touch了滑动一点距离后,up时触发。 
void  onLongPress(MotionEvent e) 
解释:Touch了不移动一直Touch down时触发 
boolean  onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) 
解释:Touch了滑动时触发。 
void  onShowPress(MotionEvent e) 
解释:Touch了还没有滑动时触发 
(与onDown,onLongPress比较 
onDown只要Touch down一定立刻触发。 
而Touchdown后过一会没有滑动先触发onShowPress再是onLongPress。 
所以Touchdown后一直不滑动,onDown->onShowPress->onLongPress这个顺序触发。


boolean  onSingleTapConfirmed(MotionEvent e) 
boolean  onSingleTapUp(MotionEvent e) 
解释:上面这两个函数都是在touch down后又没有滑动(onScroll),又没有长按(onLongPress),然后Touchup时触发。

点击一下非常快的(不滑动)Touchup: 
onDown->onSingleTapUp->onSingleTapConfirmed 
点击一下稍微慢点的(不滑动)Touchup: 
onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed

使用GestureDetector需要在View中重写onTouchEvent事件,例如:

[java] view plaincopy
  1. GestureDetector mGesture = null;  
  2. @Override  
  3.     public boolean onTouch(View v, MotionEvent event)  
  4.     {  
  5.         // TODO Auto-generated method stub  
  6.         return mGesture.onTouchEvent(event);  
  7.     }  

 详细的测试例子如下:

  1. package com.jiubang.android.gesturetest;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.util.Log;  
  6. import android.view.GestureDetector;  
  7. import android.view.MotionEvent;  
  8. import android.view.View;  
  9. import android.view.GestureDetector.SimpleOnGestureListener;  
  10. import android.view.View.OnTouchListener;  
  11. import android.widget.Button;  
  12.   
  13. public class GestureActivity extends Activity  
  14.             implements OnTouchListener  
  15. {  
  16.     private Button mButton = null;  
  17.     GestureDetector mGesture = null;  
  18.       
  19.     /** Called when the activity is first created. */  
  20.     @Override  
  21.     public void onCreate(Bundle savedInstanceState) {  
  22.         super.onCreate(savedInstanceState);  
  23.         setContentView(R.layout.main);  
  24.           
  25.         Log.i("TEST""onCreate");  
  26.         mButton = (Button)findViewById(R.id.button1);  
  27.         mButton.setOnTouchListener(this);  
  28.         mGesture = new GestureDetector(thisnew GestureListener());  
  29.     }  
  30.   
  31.     @Override  
  32.     public boolean onTouch(View v, MotionEvent event)  
  33.     {  
  34.         // TODO Auto-generated method stub  
  35.         return mGesture.onTouchEvent(event);  
  36.     }  
  37.       
  38.     class GestureListener extends SimpleOnGestureListener  
  39.     {  
  40.   
  41.         @Override  
  42.         public boolean onDoubleTap(MotionEvent e)  
  43.         {  
  44.             // TODO Auto-generated method stub  
  45.             Log.i("TEST""onDoubleTap");  
  46.             return super.onDoubleTap(e);  
  47.         }  
  48.   
  49.         @Override  
  50.         public boolean onDown(MotionEvent e)  
  51.         {  
  52.             // TODO Auto-generated method stub  
  53.             Log.i("TEST""onDown");  
  54.             return super.onDown(e);  
  55.         }  
  56.   
  57.         @Override  
  58.         public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,  
  59.                 float velocityY)  
  60.         {  
  61.             // TODO Auto-generated method stub  
  62.             Log.i("TEST""onFling:velocityX = " + velocityX + " velocityY" + velocityY);  
  63.             return super.onFling(e1, e2, velocityX, velocityY);  
  64.         }  
  65.   
  66.         @Override  
  67.         public void onLongPress(MotionEvent e)  
  68.         {  
  69.             // TODO Auto-generated method stub  
  70.             Log.i("TEST""onLongPress");  
  71.             super.onLongPress(e);  
  72.         }  
  73.   
  74.         @Override  
  75.         public boolean onScroll(MotionEvent e1, MotionEvent e2,  
  76.                 float distanceX, float distanceY)  
  77.         {  
  78.             // TODO Auto-generated method stub  
  79.             Log.i("TEST""onScroll:distanceX = " + distanceX + " distanceY = " + distanceY);  
  80.             return super.onScroll(e1, e2, distanceX, distanceY);  
  81.         }  
  82.   
  83.         @Override  
  84.         public boolean onSingleTapUp(MotionEvent e)  
  85.         {  
  86.             // TODO Auto-generated method stub  
  87.             Log.i("TEST""onSingleTapUp");  
  88.             return super.onSingleTapUp(e);  
  89.         }  
  90.           
  91.     }  
  92. }  

//以上部分内容选自网络

视屏播放界面的手势控制界面:

package com.azhibo.zhibo.view;
import java.util.HashMap;
import java.util.Map;
import io.vov.vitamio.LibsChecker;
import io.vov.vitamio.MediaPlayer;
import io.vov.vitamio.MediaPlayer.OnCompletionListener;
import io.vov.vitamio.MediaPlayer.OnErrorListener;
import io.vov.vitamio.MediaPlayer.OnPreparedListener;
import io.vov.vitamio.widget.MediaController;
import io.vov.vitamio.widget.VideoIntefaceClick;
import io.vov.vitamio.widget.VideoUtils;
import io.vov.vitamio.widget.VideoView;
import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Display;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.Toast;

import com.apple.down.assit.DownLoadInfo;
import com.azhibo.zhibo.R;
import com.umeng.analytics.MobclickAgent;

public class VideoViewActivity extends Activity {
	private static int n=0;
	//private String path = "";
	private VideoView mVideoView;
	public VideoIntefaceClick listItemCall;
	private Uri pathUri;
	private ProgressBar probar;
	private String type=null;
	private int mLayout = VideoView.VIDEO_LAYOUT_SCALE;
	private View mVolumeBrightnessLayout;
	private ImageView mOperationBg;
	private ImageView mOperationPercent;
	private AudioManager mAudioManager;
	/** 最大声音 */
	private int mMaxVolume;
	/** 当前声音 */
	private int mVolume = -1;
	/** 当前亮度 */
	private float mBrightness = -1f;	
	private GestureDetector mGestureDetector;
	private String path="";
	private String title="";
	private DownLoadInfo info=null;

	//xulongheng 播放界面的视频监听事件
	private class ListItemViewListener implements VideoIntefaceClick {
		@Override
		public void onExitVideo() {
			if(type!=null&&type.equals("1")){
				Toast.makeText(VideoViewActivity.this, "请耐心等待视频下载完毕!", Toast.LENGTH_SHORT).show();
			}else{
				Toast.makeText(VideoViewActivity.this, "本直播源需要休息一下,换一个试试吧!", Toast.LENGTH_SHORT).show();
			}
			
			Log.v("xulongheng*VideoViewActivity*onExitVideo:", "--->onExitVideo "+type);
			VideoViewActivity.this.finish();
		}

		@Override
		public void onCheckVagueVide(int statue, String url) {
			// TODO Auto-generated method stub
			Log.v("xulongheng*VideoViewActivity*onCheckVagueVide:", "--->onCheckVagueVide statue"+statue);
			Message msg=new Message();
			msg.obj=url;
			msg.what=statue;
			mHandler.sendMessage(msg);
		}
	}
	
	@Override
	public void onCreate(Bundle icicle) {
		this.requestWindowFeature(Window.FEATURE_NO_TITLE);
		this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
		
		super.onCreate(icicle);
		
		if (!LibsChecker.checkVitamioLibs(this, getClass().getName(), R.string.init_decoders, R.raw.libarm))
		{
			return;
		}
		
		setContentView(R.layout.videoview);
		mVideoView = (VideoView) findViewById(R.id.surface_view);
		probar=(ProgressBar) findViewById(R.id.probar);
		mVolumeBrightnessLayout = findViewById(R.id.operation_volume_brightness);
		mOperationBg = (ImageView) findViewById(R.id.operation_bg);
		mOperationPercent = (ImageView) findViewById(R.id.operation_percent);
		mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
		mMaxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
		
		listItemCall = new ListItemViewListener();
		mVideoView.setVideoIntefaceClick(listItemCall);
		ImageButton showLeft=(ImageButton) findViewById(R.id.showLeft);
		path=this.getIntent().getStringExtra("url");
		title=getIntent().getStringExtra("title");
//		info=(DownLoadInfo) getIntent().getSerializableExtra("info");
		
		
//		path="http://218.26.231.201/youku/69722EE89093676C988636194/030020010052A91FBF7A9A036E0AF8E178E089-4698-FC9B-45D5-E65EA8462AF1.mp4";
		Log.v("xulongheng*VideoView*uri***", ":"+path);
		pathUri = Uri.parse(path);
		type=this.getIntent().getStringExtra("type");		
		
		if(type!=null&&type.equals("1")){
			probar.setVisibility(View.GONE);
			StringBuilder builder=new StringBuilder();
			for(int i=0;i<path.split("/").length;i++){
				if(i!=0){
					builder.append(path.split("/")[i]);
					if(i!=path.split("/").length-1)
						builder.append("/");
				}
			}
			mVideoView.setVideoPath(builder.toString(),this,this.getString(R.string.app_name),this.getString(R.string.load_now));
		}else{
			VideoUtils videoUtls=new VideoUtils(this,pathUri);
			if(videoUtls.checkVagueVide()){
				Log.i("HU", "--->pathpath"+pathUri);
				videoUtls.setVideoIntefaceClick(listItemCall);
				videoUtls.doWith(pathUri.toString());
			}else{
				probar.setVisibility(View.GONE);
				mVideoView.setVideoURI(pathUri,this,this.getString(R.string.app_name),this.getString(R.string.load_now));
			}
		}		
		mVideoView.start();
		
		//xlh_add 添加播放器监听
		initVideoListen();
		mGestureDetector = new GestureDetector(this, new MyGestureListener());
			
	}
	public void initVideoListen(){
		
		mVideoView.setVideoQuality(MediaPlayer.VIDEOQUALITY_HIGH);
		mVideoView.setOnPreparedListener(new OnPreparedListener() {
			@Override
			public void onPrepared(MediaPlayer mp) {
				mVideoView.setSubShown(true);
				
				Log.v("xulongheng*VideoActivity*播放器播放准备监听:", "onPrepared");
			}
		});
		mVideoView.setOnCompletionListener(new OnCompletionListener() {
			@Override
			public void onCompletion(MediaPlayer arg0) {
				n++;
			
				Toast.makeText(VideoViewActivity.this, "播放即将结束!", Toast.LENGTH_SHORT).show();			
				VideoViewActivity.this.finish();
				Log.v("xulongheng*VideoActivity*播放器播放完成监听:", "onCompletion"+n);
			}

		});
		
		mVideoView.setOnErrorListener(new OnErrorListener() {
			
			@Override
			public boolean onError(MediaPlayer arg0, int arg1, int arg2) {
				//播放源错误统计分析 未完成
				Map<String, String> source = new HashMap<String, String>();
				source.put("url", path);
				if(title!=null&&!title.equals(""))
					source.put("title", title);
				
				
				MobclickAgent.onEvent(VideoViewActivity.this, "ErrorSource",source);	
				
				Toast.makeText(VideoViewActivity.this, "本视频无法播放", Toast.LENGTH_SHORT).show();			
				VideoViewActivity.this.finish();
				
				Log.v("xulongheng*VideoActivity*播放器播放错误监听:", "onError:"+arg1+"/"+arg2);
				return false;
			}
		});
		mVideoView.setMediaController(new MediaController(this));
		
		
		
	}
	

	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		if (mVideoView != null)
		{
			mVideoView.setVideoLayout(mLayout, 0);
		}
		
		super.onConfigurationChanged(newConfig);
	}
	
	public Handler mHandler = new Handler() {
		@SuppressWarnings("unchecked")
		public void handleMessage(Message msg) {
			probar.setVisibility(View.GONE);
			
			switch(msg.what){
			case 0:
				mVideoView.setVideoURI(Uri.parse(msg.obj.toString()),VideoViewActivity.this,VideoViewActivity.this.getString(R.string.app_name),VideoViewActivity.this.getString(R.string.load_now));
				break;
			case 1:
				mVideoView.setVideoURI(Uri.parse(msg.obj.toString()),VideoViewActivity.this,VideoViewActivity.this.getString(R.string.app_name),VideoViewActivity.this.getString(R.string.load_now));
				break;
			}
		}
	};
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		if (mGestureDetector.onTouchEvent(event))
			return true;

		// 处理手势结束 多点触控之MotionEvent.ACTION_MASK作用
		switch (event.getAction() & MotionEvent.ACTION_MASK) {
		case MotionEvent.ACTION_UP:
			endGesture();
			break;
		}

		return super.onTouchEvent(event);
	}

	/** 手势结束 */
	private void endGesture() {
		mVolume = -1;
		mBrightness = -1f;

		// 隐藏
		mDismissHandler.removeMessages(0);
		mDismissHandler.sendEmptyMessageDelayed(0, 500);
	}

	//xulongheng 触屏横向调音量
	private class MyGestureListener extends SimpleOnGestureListener {

		/** 双击 */
		@Override
		public boolean onDoubleTap(MotionEvent e) {
			if (mLayout == VideoView.VIDEO_LAYOUT_SCALE)
				mLayout = VideoView.VIDEO_LAYOUT_ZOOM;
			else
				mLayout = VideoView.VIDEO_LAYOUT_SCALE;
			
			Log.d("Scale = ", Integer.toString(mLayout));
			
			if (mVideoView != null)
			{
				mVideoView.setVideoLayout(mLayout, 0);
			}
			
			return true;
		}

		/** 左右两边滑动调节音量两度 */
		@Override
		public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
			float mOldX = e1.getX(), mOldY = e1.getY();
			int y = (int) e2.getRawY();
			Display disp = getWindowManager().getDefaultDisplay();
			int windowWidth = disp.getWidth();
			int windowHeight = disp.getHeight();

			if (mOldX > windowWidth * 4.0 / 5)// 右边滑动
				onVolumeSlide((mOldY - y) / windowHeight);
			else if (mOldX < windowWidth / 5.0)// 左边滑动
				onBrightnessSlide((mOldY - y) / windowHeight);

			return super.onScroll(e1, e2, distanceX, distanceY);
		}
	}
	
	/** xulongheng定时隐藏 */
	private Handler mDismissHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			mVolumeBrightnessLayout.setVisibility(View.GONE);
		}
	};

	/**
	 * 滑动改变声音大小
	 * 
	 * @param percent
	 */
	private void onVolumeSlide(float percent) {
		if (mVolume == -1) {
			mVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
			if (mVolume < 0)
				mVolume = 0;

			// 显示
			mOperationBg.setImageResource(R.drawable.video_volumn_bg);
			mVolumeBrightnessLayout.setVisibility(View.VISIBLE);
		}

		int index = (int) (percent * mMaxVolume) + mVolume;
		if (index > mMaxVolume)
			index = mMaxVolume;
		else if (index < 0)
			index = 0;

		// 变更声音
		mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, index, 0);

		// 变更进度条
		ViewGroup.LayoutParams lp = mOperationPercent.getLayoutParams();
		lp.width = findViewById(R.id.operation_full).getLayoutParams().width * index / mMaxVolume;
		mOperationPercent.setLayoutParams(lp);
	}

	/**
	 * xulongheng 滑动改变亮度
	 * 
	 * @param percent
	 */
	private void onBrightnessSlide(float percent) {
		if (mBrightness < 0) {
			mBrightness = getWindow().getAttributes().screenBrightness;
			if (mBrightness <= 0.00f)
				mBrightness = 0.50f;
			if (mBrightness < 0.01f)
				mBrightness = 0.01f;

			// 显示
			mOperationBg.setImageResource(R.drawable.video_brightness_bg);
			mVolumeBrightnessLayout.setVisibility(View.VISIBLE);
		}
		WindowManager.LayoutParams lpa = getWindow().getAttributes();
		lpa.screenBrightness = mBrightness + percent;
		if (lpa.screenBrightness > 1.0f)
			lpa.screenBrightness = 1.0f;
		else if (lpa.screenBrightness < 0.01f)
			lpa.screenBrightness = 0.01f;
		getWindow().setAttributes(lpa);

		ViewGroup.LayoutParams lp = mOperationPercent.getLayoutParams();
		lp.width = (int) (findViewById(R.id.operation_full).getLayoutParams().width * lpa.screenBrightness);
		mOperationPercent.setLayoutParams(lp);
	}	
}


阅读更多
上一篇Android实现计时与倒计时的几种方法
下一篇Android判断当前网络是否可用
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭