Android onTouchEvent事件

根据用户的触摸判断滑动方向,选择弹出popupWindow 或者dialog ,也可以切换界面,定义切换动画


定义接口:

/**
 * According to the Angle of the sliding range sliding direction
 * @author LanYan
 *
 */
public interface OnEventListener {

	/**
	 * ←
	 */
	void onLeft();
	/**
	 * ↑
	 */
	void onTop();
	/**
	 * →
	 */
	void onRight();
	/**
	 * ↓
	 */
	void onBottom();
	/**
	 * ↗
	 */
	void onNortheast();
	/**
	 * ↖
	 */
	void onNorthwest();
	/**
	 * ↙
	 */
	void onSouthwest();
	/**
	 * ↘
	 */
	void onSoutheast();
	/**
	 * 触摸屏幕
	 */
	void onTouch();
	/**
	 * 事件分发
	 */
	EventType onEventDistribute();
	

方法调用工具类:

import android.view.MotionEvent;
import android.view.View;

public class OnEventTouchFactory {

	private static OnEventTouchFactory mCurrent;
	private static OnEventListener mListener;
	private int mLastEventX;
	private int mLastEventY;
	private EventType mType;
	private int mDistance = 50;
	private double cos;
	private double result;
	private EventType mCurrentType = null;

	public OnEventTouchFactory() {

	}

	public static OnEventTouchFactory getInstance(OnEventListener listener) {
		mListener = listener;
		if (mCurrent == null) {
			mCurrent = new OnEventTouchFactory();
		}
		return mCurrent;
	}

	public boolean onTouch(View v, MotionEvent event) {
		// TODO Auto-generated method stub
		boolean  status=false;
		mListener.onTouch();
		int eventX = (int) event.getX();
		int eventY = (int) event.getY();
		int action = event.getAction();
		if (action == MotionEvent.ACTION_DOWN) {
			mLastEventX = eventX;
			mLastEventY = eventY;
			mCurrentType = mListener.onEventDistribute();
			status=true;
		} else if (action == MotionEvent.ACTION_MOVE) {
			if (mCurrentType == EventType.normal) {
				cos = getAngle(eventX, eventY, mLastEventX, mLastEventY);
				result = getDistance(mLastEventX, mLastEventY, eventX, eventY);
				/**
				 * EeventType: Left ←: [157.5,202.5] Top ↑: [67.5,112.5] Right
				 * →: [337.5,360]&&[0,22.5] Bottom ↓: [247.5,292.5] Northwest ↖:
				 * [112.5,157.5] ┅┅┅┅┅ ┅┅┅┅┅ ┅┅┅┅┅ Southeast ↘: [292.5,337.5] ┇
				 * Southwest ↙: [202.5,247.5] ┇ Northeast ↗: [22.5,67.5] ┇ ┇
				 * VelocityXY ↖↗ --------------- ↙ ↘ ┅┅┅┅┅ ┅┅┅┅┅ ┅┅┅┅┅┅┅┅┅┅
				 * ┅┅┅┅┅┇
				 */

				if ((cos >= 0 && cos <= 22.5) || (cos >= 337.5 && cos <= 360)) {
					mType = EventType.left;
				}

				else if (cos > 22.5 && cos <= 67.5) {
					mType = EventType.nortwest;
				}

				else if (cos >= 67.5 && cos <= 112.5) {
					mType = EventType.top;
				}
				else if (cos > 112.5 && cos < 157.5) {
					mType = EventType.northeast;
				}

				else if (cos >= 157.5 && cos <= 202.5) {
					mType = EventType.right;
				}

				else if (cos > 202.5 && cos < 247.5) {
					mType = EventType.southeast;
				}

				else if (cos >= 247.5 && cos <= 292.5) {
					mType = EventType.bottom;
				}

				else if (cos > 292.5 && cos < 337.5) {
					mType = EventType.southwest;
				}
				status=true;
			}  else if (mCurrentType == EventType.complete) {
				status= false;
			}
		} else if (action == MotionEvent.ACTION_UP) {
			if (mType == EventType.right && result > mDistance) {
				mListener.onRight();
			} else if (mType == EventType.top && result > mDistance) {
				mListener.onTop();
			} else if (mType == EventType.northeast && result > mDistance) {
				mListener.onNortheast();
			} else if (mType == EventType.nortwest && result > mDistance) {
				mListener.onNorthwest();
			} else if (mType == EventType.left && result > mDistance) {
				mListener.onLeft();
			} else if (mType == EventType.southeast && result > mDistance) {
				mListener.onSoutheast();
			} else if (mType == EventType.southwest && result > mDistance) {
				mListener.onSouthwest();
			} else if (mType == EventType.bottom && result > mDistance) {
				mListener.onBottom();
			}
			status=  true;
		}
		return status;
	}

	public double getAngle(int px1, int py1, int px2, int py2) {
		// 两点的x、y值
		int x = px2 - px1;
		int y = py2 - py1;
		double hypotenuse = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
		// 斜边长度
		double cos = x / hypotenuse;
		double radian = Math.acos(cos);
		// 求出弧度
		double angle = 180 / (Math.PI / radian);
		// 用弧度算出角度
		if (y < 0) {
			angle = 180 + (180 - angle);
		} else if ((y == 0) && (x < 0)) {
			angle = 180;
		}
		return angle;
	}

	/**
	 * 获取两点的距离
	 * 
	 * @param x1
	 * @param y1
	 * @param x2
	 * @param y2
	 * @return
	 */
	public double getDistance(int x1, int y1, int x2, int y2) {
		double d = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
		return Math.sqrt(d);
	}


	public enum EventType {
		left, top, right, bottom, nortwest, southeast, southwest, northeast,
		/**
		 * event不向下分发
		 */
		normal,
		/**
		 * 完全向下分发
		 */
		complete
		
	}
}

BaseActivity类:

import com.example.base.OnEventTouchFactory.EventType;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.Toast;

public abstract class BaseActivity extends Activity implements OnTouchListener, OnEventListener{
	
	protected Class<?> mLeftClass=null;
	protected Class<?> mRightClass=null;
	protected Class<?> mTopClass=null;
	protected Class<?> mBottomClass=null;
	
	protected Class<?> mNortheastClass=null;
	protected Class<?> mNorthwestClass=null;
	protected Class<?> mSoutheastClass=null;
	protected Class<?> mSouthwestClass=null;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setTheme();
		setContentView(getLayoutResID());
		configClass();
		initialization();
	}

	public abstract int getLayoutResID();
	public void setTheme(){

	}
	public void configClass(){
		
	}
	public void initialization(){

	}
	
	/***********************************onTouch*********************************************/

	@Override
	public boolean onTouch(View v, MotionEvent event) {
		// TODO Auto-generated method stub
		if(OnEventTouchFactory.getInstance(this).onTouch(v, event)){
			return true;
		}
		
		return false;
	}
	
	@Override
	public void onLeft() {
		// TODO Auto-generated method stub

	}

	@Override
	public void onTop() {
		// TODO Auto-generated method stub

	}

	@Override
	public void onRight() {
		// TODO Auto-generated method stub

	}

	@Override
	public void onBottom() {
		// TODO Auto-generated method stub

	}

	@Override
	public void onNortheast() {
		// TODO Auto-generated method stub

	}

	@Override
	public void onNorthwest() {
		// TODO Auto-generated method stub

	}

	@Override
	public void onSouthwest() {
		// TODO Auto-generated method stub

	}

	@Override
	public void onSoutheast() {
		// TODO Auto-generated method stub

	}

	@Override
	public void onTouch() {
		// TODO Auto-generated method stub

	}
	
	
	
	@Override
	public EventType onEventDistribute() {
		// TODO Auto-generated method stub
		return EventType.normal;
	}
	/***********************************Method*********************************************/
	public void startActivity(Class<?> cls){
		Intent intent=new Intent();
		intent.setClass(this, cls);
		startActivity(intent);
	}
	public void startActivity(Class<?> cls,boolean isFinish){
		Intent intent=new Intent();
		intent.setClass(this, cls);
		startActivity(intent);
		if(isFinish){
			finish();
		}
	}
	
	public void startActivityWithAnimation(Class<?> cls,int enterAnim,int exitAnim){
		Intent intent=new Intent();
		intent.setClass(this, cls);
		startActivity(intent);
		overridePendingTransition(enterAnim, exitAnim);
	}
	
	public void startActivity(Class<?> cls,boolean isFinish,int enterAnim,int exitAnim){
		Intent intent=new Intent();
		intent.setClass(this, cls);
		startActivity(intent);
		if(isFinish){
			finish();
		}
		overridePendingTransition(enterAnim, exitAnim);
	}
	public void ShowSToast(String message){
		Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
	}
	public void ShowLToast(String message){
		Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
	}
}

测试Activity类:

import android.text.method.ScrollingMovementMethod;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.example.base.BaseActivity;
import com.example.base.OnEventTouchFactory.EventType;

public class MainActivity extends BaseActivity {

	@Override
	public int getLayoutResID() {
		// TODO Auto-generated method stub
		return R.layout.activity_main;
	}
	
	@Override
	public void configClass() {
		// TODO Auto-generated method stub
		super.configClass();
	}
	
	@Override
	public void initialization() {
		// TODO Auto-generated method stub
		super.initialization();
		RelativeLayout parent=(RelativeLayout)findViewById(R.id.parent);
		TextView child=(TextView)findViewById(R.id.child);
		
		child.setMovementMethod(ScrollingMovementMethod.getInstance());
	    parent.setOnTouchListener(this);
	}
	@Override
	public void onRight() {
		// TODO Auto-generated method stub
		super.onRight();
		ShowSToast("right");
	}
	@Override
	public void onTop() {
		// TODO Auto-generated method stub
		super.onTop();
		ShowSToast("top");
	}
	@Override
	public void onLeft() {
		// TODO Auto-generated method stub
		super.onLeft();
		ShowSToast("left");
	}
	@Override
	public void onBottom() {
		// TODO Auto-generated method stub
		super.onBottom();
		ShowSToast("bottom");
	}
	@Override
	public void onNortheast() {
		// TODO Auto-generated method stub
		super.onNortheast();
		ShowSToast("northeast");
	}
	@Override
	public void onNorthwest() {
		// TODO Auto-generated method stub
		super.onNorthwest();
		ShowSToast("northwest");
	}
	@Override
	public void onSoutheast() {
		// TODO Auto-generated method stub
		super.onSoutheast();
		ShowSToast("southeast");
	}
	@Override
	public void onSouthwest() {
		// TODO Auto-generated method stub
		super.onSouthwest();
		ShowSToast("southwest");
	}
	@Override
	public void onTouch() {
		// TODO Auto-generated method stub
		super.onTouch();
	}

	@Override
	public EventType onEventDistribute() {
		// TODO Auto-generated method stub
		return super.onEventDistribute();
	}
	
	
}

BaseActivity 类实现了OnEventListener,并将该类抽象,那么在子类里面需要手势操作 绑定Touch事件即可,通过OnEventListener的回调函数处理手势操作

这是简单的手势操作,复杂点的(比如onTouch的冲突)需要涉及到 类:View ViewGroup Activity  ,涉及到的方法:dispatchTouchEvent(事件分发)  onInterceptTouchEvent(事件拦截) onTouch onTouchEvent..Activity 里面不含onInterceptTouchEvent方法


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。