Android关于OnTouch 和OnClick同时调用冲突的解决方案
来源:互联网 发布:全球潮汐软件下载 编辑:程序博客网 时间:2024/06/03 16:49
原文
Button的onTouch,onClick,onLongClick事件发生先后顺序和关联:
一,onTouch返回false
首先是onTouch事件的down事件发生,此时,如果长按,触发onLongClick事件;
然后是onTouch事件的up事件发生,up完毕,最后触发onClick事件。
二,onTouch返回true
首先是onTouch事件的down事件发生,然后是onTouch事件的up事件发生;期间不触发onClick和onLongClick事件
三,onTouch:down返回true,up返回false:结果同二。
机制分析:
onTouch事件中:down事件返回值标记此次事件是否为点击事件(返回false,是点击事件;返回true,不记为点击事件),而up事件标记此次事件结束时间,也就是判断是否为长按。
只要当down返回true时候,系统将不把本次事件记录为点击事件,也就不会触发onClick或者onLongClick事件了。因此尽管当up的时候返回false,系统也不会继续触发onClick事件了。
四,onTouch:down返回false,up返回true:
首先是onTouch事件的down事件发生,此时:
长按,触发onLongClick事件,然后是onTouch事件的up事件发生,完毕。
短按,先触发onTouch的up事件, 到一定时间后,自动触发onLongClick事件。
机制分析:
onTouch事件中:down事件返回值标记此次事件是否为点击事件(返回false,是点击事件;返回true,不记为点击事件),而up事件标记此次事件结束时间,也就是判断是否为长按。
当down返回false,标记此次事件为点击事件,而up返回了true,则表示此次事件一直没有结束,也就是一直长按下去了,达到长按临界时间后,自然触发长按事件,而onClick事件没有触发到
public class ImageZoomActivity extends Activity implements OnTouchListener { private static final String TAG = "Touch"; // These matrices will be used to move and zoom image Matrix matrix = new Matrix(); Matrix savedMatrix = new Matrix(); // We can be in one of these 3 states static final int NONE = 0; static final int DRAG = 1; static final int ZOOM = 2; int mode = NONE; // Remember some things for zooming PointF start = new PointF(); PointF mid = new PointF(); float oldDist = 1f; private ImageView view; private boolean keyUpDown=false; private int timer=0; /* (non-Javadoc) * @see android.app.Activity#onCreate(android.os.Bundle) */@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.touch); view = (ImageView) findViewById(R.id.imageView); Intent intent=getIntent();// Drawable drawable=loadImgByFilePath(intent.getStringExtra("toZoom")); view.setImageURI(Uri.parse(intent.getStringExtra("toZoom"))); view.setOnTouchListener(this); } private Handler clickHandler = new Handler(){ @Override public void handleMessage(Message msg) { if(msg.what==0){ keyUpDown=true; keyUpDownListener(); }else if(msg.what==1){ keyUpDown=false; if(timer<=1) ImageZoomActivity.this.finish();//此处即为OnClick处理对应部分,只需在此处添中处理代码即可. else timer=0; } } }; private int keyUpDownListener() { new Thread(){ public void run(){ while(keyUpDown){ try { sleep(200); timer++; Log.d("info","timing:timer="+timer); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); return timer; } @Override public boolean onTouch(View v, MotionEvent event) { ImageView view = (ImageView) v; // Dump touch event to log// dumpEvent(event); // Handle touch events here... switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: savedMatrix.set(matrix); //設置初始點位置 start.set(event.getX(), event.getY()); Log.d(TAG, "mode=DRAG"); clickHandler.sendEmptyMessage(0); mode = DRAG; break; case MotionEvent.ACTION_POINTER_DOWN: oldDist = spacing(event); Log.d(TAG, "oldDist=" + oldDist); if (oldDist > 10f) { savedMatrix.set(matrix); midPoint(mid, event); mode = ZOOM; Log.d(TAG, "mode=ZOOM"); } break; case MotionEvent.ACTION_UP:clickHandler.sendEmptyMessage(1); case MotionEvent.ACTION_POINTER_UP: mode = NONE; Log.d(TAG, "mode=NONE"); break; case MotionEvent.ACTION_MOVE: if (mode == DRAG) { // ... matrix.set(savedMatrix); matrix.postTranslate(event.getX() - start.x, event.getY() - start.y); } else if (mode == ZOOM) { float newDist = spacing(event); Log.d(TAG, "newDist=" + newDist); if (newDist > 10f) { matrix.set(savedMatrix); float scale = newDist / oldDist; matrix.postScale(scale, scale, mid.x, mid.y); } } break; } view.setImageMatrix(matrix); return true; // indicate event was handled } /** Determine the space between the first two fingers */ private float spacing(MotionEvent event) { float x = event.getX(0) - event.getX(1); float y = event.getY(0) - event.getY(1); return FloatMath.sqrt(x * x + y * y); } /** Calculate the mid point of the first two fingers */ private void midPoint(PointF point, MotionEvent event) { float x = event.getX(0) + event.getX(1); float y = event.getY(0) + event.getY(1); point.set(x / 2, y / 2); } }
PS:如果OnTouch返回true或者返回false都不行的时候,可以尝试返回
super.onTouchEvent(event)
- Android关于OnTouch 和OnClick同时调用冲突的解决方案
- Android关于OnTouch 和OnClick同时调用冲突的解决方案
- Android关于OnTouch 和OnClick同时调用冲突的解决方案
- Android关于OnTouch 和OnClick同时调用冲突的解决方案
- Android关于OnTouch 和OnClick同时调用冲突的解决方案
- Android关于OnTouch 和OnClick同时调用冲突的解决方案
- 关于OnTouch 和OnClick同时调用冲突的解决方案
- Android关于OnTouch 和OnClick同时调用冲突 重复
- Android OnTouch 和OnClick同时调用冲突问题(单个View)
- 关于android下面girdview item同时实现onclick和ontouch的一点心得.
- Android关于OnTouch 和OnClick
- android 悬浮框的OnTouch和OnClick事件同时存在
- Android 中 onTouch 和OnClick 冲突的处理
- Android 中 onTouch 和OnClick 冲突的处理
- android ontouch和onclick冲突处理
- Android 中 onTouch 和OnClick 冲突的处理(onTouchEvent返回true时与onclick冲突)
- 悬浮窗onTouch和onCLick的冲突
- android onclick与ontouch和scroll监听冲突的解决方法 类似QQHD拖动窗口效果
- ViewPager+Fragment 实现某个Fragment处于可见时候加载数据
- android ViewPager实现广告图轮播
- 《大话数据结构》
- 在Windows环境给Oracle打补丁
- 杭电OJ 2001
- Android关于OnTouch 和OnClick同时调用冲突的解决方案
- Thymeleaf 之 内置对象、定义变量、URL参数及标签自定义属性
- iOS 记住网页(UIWebView)上次浏览的位置
- 自定义网桥
- Warning:Gradle version 2.10 is required. Current version is 2.4. If using the gradle wrapper, try ed
- cxf和spring开发web service--服务器端
- 《大话数据结构》
- 百度云网盘下载无反应javascript:void(0)救急办法
- Swift 3.0 label富文本