android view OnTouchEvent 中与此同时处理 onClick,onLongClick,和左右移动事件
android view OnTouchEvent 中同时处理 onClick,onLongClick,和左右移动事件
欲实现的效果是:当手机按住屏幕时,如果在指定的时间内没有移动(如500毫秒),那么进入长按模式,此时手指在屏幕上移动都算作长按模式。如果手机按住屏幕就立马移动,那么就算作移动模式。如果没有移动也没有超过规定时间内则为单击。
思路:在Down的时候开启一个线程然后延迟500ms(长按触发的时间)后执行,然后再UP的时候判断如果按住的时间没有超过了500ms那么代码长按事件没有触发,然后执行连续点击事件的逻辑,同时删除掉Handler队列中的处理长按事件的线程。
OnTouchEventDemoActivity.class
public class OnTouchEventDemoActivity extends Activity { private Button mButton; /**********************************touch事件*********************************************/ private static final long LONG_PRESS_TIME = 500; /** * 当前触摸点相对于屏幕的坐标 */ private float mCurrentInScreenX; private float mCurrentInScreenY; /** * 触摸点按下时的相对于屏幕的坐标 */ private float mDownInScreenX; private float mUpInScreenX; private float mDownInScreenY; /** * 当前点击时间 */ private long mCurrentClickTime; private Handler mBaseHandler = new Handler(); @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.on_touch_event_demo_activity); viewInit(); listenerInit(); } private void viewInit(){ mButton = (Button) findViewById(R.id.on_touch_event_demo_button); } private void listenerInit(){ mButton.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub //当前坐标 mCurrentInScreenX = event.getRawX(); mCurrentInScreenY = event.getRawY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: //记录Down下时的坐标 mDownInScreenX = event.getRawX(); mDownInScreenY = event.getRawY(); //记录当前点击的时间 mCurrentClickTime = Calendar.getInstance().getTimeInMillis(); //开一个线程,延迟LONG_PRESS_TIME时间 mLongPressedThread = new LongPressedThread(); mBaseHandler.postDelayed(mLongPressedThread,LONG_PRESS_TIME); break; case MotionEvent.ACTION_UP: { mUpInScreenX = event.getRawX(); if(!isMoved()){ //如果按住的时间超过了长按时间,那么其实长按事件已经出发生了,这个时候把数据清零 if(Calendar.getInstance().getTimeInMillis() - mCurrentClickTime <= LONG_PRESS_TIME){ //取消注册的长按事件 mBaseHandler.removeCallbacks(mLongPressedThread); //这里处理长按事件 Toast.makeText(OnTouchEventDemoActivity.this.getApplicationContext(), "单击事件处理",Toast.LENGTH_SHORT).show(); } }else{ //取消注册的长按事件 mBaseHandler.removeCallbacks(mLongPressedThread); //UP的时候Move过 if((mUpInScreenX-mDownInScreenX)>200 ){ Toast.makeText(OnTouchEventDemoActivity.this.getApplicationContext(), "左移事件处理",Toast.LENGTH_SHORT).show(); }else if((mUpInScreenX-mDownInScreenX) <-200){ Toast.makeText(OnTouchEventDemoActivity.this.getApplicationContext(), "右移事件处理",Toast.LENGTH_SHORT).show(); } } break; } } return true; } }); } /** * 判断是否移动 * @return */ private boolean isMoved(){ //允许有5的偏差 在判断是否移动的时候 if(Math.abs(mDownInScreenX - mCurrentInScreenX) <= 10 && Math.abs(mDownInScreenY - mCurrentInScreenY) <= 10 ){ return false; }else{ return true; } } private LongPressedThread mLongPressedThread; public class LongPressedThread implements Runnable{ @Override public void run() { //这里处理长按事件 Toast.makeText(OnTouchEventDemoActivity.this.getApplicationContext(), "长按事件处理",Toast.LENGTH_SHORT).show(); } } }on_touch_event_demo_activity.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <Button android:id="@+id/on_touch_event_demo_button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="测试按钮" android:textSize="13sp" /> </LinearLayout>