根据用户的触摸判断滑动方向,选择弹出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 } }
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(); } }
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(); } }
这是简单的手势操作,复杂点的(比如onTouch的冲突)需要涉及到 类:View ViewGroup Activity ,涉及到的方法:dispatchTouchEvent(事件分发) onInterceptTouchEvent(事件拦截) onTouch onTouchEvent..Activity 里面不含onInterceptTouchEvent方法
原文地址:http://blog.csdn.net/anddroid_lanyan/article/details/45581677