锁定老帖子 主题:Android自定义长按事件
精华帖 (0) :: 良好帖 (5) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-11-06
最后修改:2010-11-11
Android系统自带了长按事件,setOnLongClickListener即可监听。但是有时候,你不希望用系统的长按事件,比如当希望长按的时间更长一点的时候。这时候就需要自己来定义这个长按事件了。 package chroya.fun; import android.content.Context; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; public class LongPressView1 extends View{ private int mLastMotionX, mLastMotionY; //是否移动了 private boolean isMoved; //是否释放了 private boolean isReleased; //计数器,防止多次点击导致最后一次形成longpress的时间变短 private int mCounter; //长按的runnable private Runnable mLongPressRunnable; //移动的阈值 private static final int TOUCH_SLOP = 20; public LongPressView1(Context context) { super(context); mLongPressRunnable = new Runnable() { @Override public void run() { mCounter--; //计数器大于0,说明当前执行的Runnable不是最后一次down产生的。 if(mCounter>0 || isReleased || isMoved) return; performLongClick(); } }; } public boolean dispatchTouchEvent(MotionEvent event) { int x = (int) event.getX(); int y = (int) event.getY(); switch(event.getAction()) { case MotionEvent.ACTION_DOWN: mLastMotionX = x; mLastMotionY = y; mCounter++; isReleased = false; isMoved = false; postDelayed(mLongPressRunnable, ViewConfiguration.getLongPressTimeout()); break; case MotionEvent.ACTION_MOVE: if(isMoved) break; if(Math.abs(mLastMotionX-x) > TOUCH_SLOP || Math.abs(mLastMotionY-y) > TOUCH_SLOP) { //移动超过阈值,则表示移动了 isMoved = true; } break; case MotionEvent.ACTION_UP: //释放了 isReleased = true; break; } return true; } } 代码里注释的比较清楚。主要思路是在down的时候,让一个Runnable一段时间后执行,如果时间到了,没有移动超过定义的阈值,也没有释放,则触发长按事件。在真实环境中,当长按触发之后,还需要将后来的move和up事件屏蔽掉。此处是示例,就略去了。 package chroya.fun; import android.content.Context; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; public class LongPressView2 extends View{ private int mLastMotionX, mLastMotionY; //是否移动了 private boolean isMoved; //长按的runnable private Runnable mLongPressRunnable; //移动的阈值 private static final int TOUCH_SLOP = 20; public LongPressView2(Context context) { super(context); mLongPressRunnable = new Runnable() { @Override public void run() { performLongClick(); } }; } public boolean dispatchTouchEvent(MotionEvent event) { int x = (int) event.getX(); int y = (int) event.getY(); switch(event.getAction()) { case MotionEvent.ACTION_DOWN: mLastMotionX = x; mLastMotionY = y; isMoved = false; postDelayed(mLongPressRunnable, ViewConfiguration.getLongPressTimeout()); break; case MotionEvent.ACTION_MOVE: if(isMoved) break; if(Math.abs(mLastMotionX-x) > TOUCH_SLOP || Math.abs(mLastMotionY-y) > TOUCH_SLOP) { //移动超过阈值,则表示移动了 isMoved = true; removeCallbacks(mLongPressRunnable); } break; case MotionEvent.ACTION_UP: //释放了 removeCallbacks(mLongPressRunnable); break; } return true; } } 思路跟第一种差不多,不过,在移动超过阈值和释放之后,会将Runnable从事件队列中remove掉,长按事件也就不会再触发了。源码中实现长按的原理也基本如此。
工程见附件。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-11-10
楼主可以提供源码下载不?好学习下,谢谢
|
|
返回顶楼 | |
发表时间:2010-11-11
能否与我们一起分享源码呢?
|
|
返回顶楼 | |
发表时间:2010-11-11
热血pk007 写道 楼主可以提供源码下载不?好学习下,谢谢
源码已附上。 |
|
返回顶楼 | |
发表时间:2010-11-14
这个运行之后怎么是黑屏?触屏没反应啊
|
|
返回顶楼 | |
发表时间:2010-11-14
热血pk007 写道 这个运行之后怎么是黑屏?触屏没反应啊
你看代码啊,log里面会打出来的。 |
|
返回顶楼 | |
发表时间:2010-11-27
chroya 写道 热血pk007 写道 这个运行之后怎么是黑屏?触屏没反应啊
你看代码啊,log里面会打出来的。 什么都没有啊 |
|
返回顶楼 | |
发表时间:2010-12-05
chroya 写道 热血pk007 写道 这个运行之后怎么是黑屏?触屏没反应啊
你看代码啊,log里面会打出来的。 长按时间也没有加长啊,和内部自带的长按事件是相同的时间长短啊 |
|
返回顶楼 | |
发表时间:2010-12-05
热血pk007 写道 chroya 写道 热血pk007 写道 这个运行之后怎么是黑屏?触屏没反应啊
你看代码啊,log里面会打出来的。 长按时间也没有加长啊,和内部自带的长按事件是相同的时间长短啊 是的,长按事件是用的系统的时间ViewConfiguration.getLongPressTimeout(),如果你需要加长,可以自己更改,把这个改成想要的时间。 |
|
返回顶楼 | |
发表时间:2010-12-06
长按键,我之前也做过了,但是感觉你的代码比我的少点,感谢你!
|
|
返回顶楼 | |