`
johnnycmj
  • 浏览: 36772 次
  • 性别: Icon_minigender_1
  • 来自: 福州
社区版块
存档分类
最新评论

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>
 
 
分享到:
评论

相关推荐

    android中的事件处理

    在Android开发中,事件处理是构建用户界面时不可或缺的一部分,它允许应用程序响应用户的操作和系统的各种事件。Android事件处理机制主要包括两种方式:监听器(Listener)模式和消息队列(Message Queue)。本篇...

    android click 和onTouch 事件处理机制.

    在同一个`View`中,如果同时覆盖了`onClick`、`onLongClick`和`onTouchEvent`,那么事件的处理顺序是这样的:`onTouchEvent`首先接收到`ACTION_DOWN`,然后可能会启动检查长按的定时器;当`ACTION_UP`到来时,如果...

    android区分点击事件[参考].pdf

    本文将深入探讨如何在Android中区分不同的点击事件,包括`onTouchEvent`、`onClick`和`onLongClick`,以及它们之间的关系和触发机制。 首先,我们来看`onTouchEvent`。`onTouchEvent`主要用于处理触摸屏幕时的一...

    详谈Android中onTouch与onClick事件的关系(必看)

    首先,`onTouch`事件是Android中用于处理触摸屏事件的接口,它通过`View.OnTouchListener`实现。当用户与屏幕进行交互时,`onTouch`方法会被调用,接收到一个`MotionEvent`对象,该对象包含了触摸事件的详细信息,如...

    android界面编程基础

    1. onTouchEvent(MotionEvent event):处理触摸事件,包括ACTION_DOWN(按下)、ACTION_UP(抬起)、ACTION_MOVE(移动)等。 2. setOnClickListener(View.OnClickListener listener):设置点击事件监听器,当View被...

    android面试题集锦(珍藏)

    如果事件传递到最内层的`View`后,`onTouchEvent()`返回`false`,那么事件将以冒泡方式向上回传,依次调用父`View`的`onTouchEvent()`方法,直到找到能处理事件的`View`或最终由`Activity`处理。 **2. 事件分发注意...

    详细分析Android中onTouch事件传递机制

    此外,`onTouchEvent`还与`onClick`和`onLongClick`等其他事件处理方法有所关联。`onClick`通常用于点击事件,而`onLongClick`则用于长按事件。尽管它们的触发方式不同,但它们都依赖于`onTouchEvent`来检测用户的...

    FlowWindow:一个浮动的按钮例子,可以移动、点击、长按等操作

    在Android开发中,实现这样的功能需要对Android的视图系统有深入的理解,特别是对`View`类和`ViewGroup`类的掌握。`FlowWindow`可能是自定义的一个`View`或`ViewGroup`子类,通过重写其中的关键方法来实现各种交互...

Global site tag (gtag.js) - Google Analytics