根据用户的触摸判断滑动方向,选择弹出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方法