欲实现的效果是:当手机按住屏幕时,如果在指定的时间内没有移动(如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>