使用Android接收onTouch和onClick事件

我有一个需要处理onTouch手势 onClick事件的视图。 什么是实现这一目标的正确方法?

我有一个onTouchListener和一个onTouchListener在视图上设置。 每当我触摸视图,首先触发onTouch事件,然后onClick 。 但是,从onTouch事件处理程序,我必须返回truefalse 。 返回true意味着事件正在被消耗,所以android事件系统不会再传播事件。

因此,一个onClick事件永远不会生成,至less我的onClick侦听器是永远不会触发,当我在我的onTouch事件处理程序返回true 。 另一方面,返回false没有选项,因为这可以防止onTouch侦听器接收任何进一步的必要事件来识别手势。 通常解决这个问题的方法是什么?

Solutions Collecting From Web of "使用Android接收onTouch和onClick事件"

在你的GestureDetector中,你可以直接调用callOnClick()。 请注意,View.callOnClick API需要API级别15.只需尝试一下。

  // Create a Gesturedetector GestureDetector mGestureDetector = new GestureDetector(context, new MyGestureDetector()); // Add a OnTouchListener into view m_myViewer.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return mGestureDetector.onTouchEvent(event); } }); private class MyGestureDetector extends GestureDetector.SimpleOnGestureListener { public boolean onSingleTapUp(MotionEvent e) { // ---Call it directly--- callOnClick(); return false; } public void onLongPress(MotionEvent e) { } public boolean onDoubleTap(MotionEvent e) { return false; } public boolean onDoubleTapEvent(MotionEvent e) { return false; } public boolean onSingleTapConfirmed(MotionEvent e) { return false; } public void onShowPress(MotionEvent e) { LogUtil.d(TAG, "onShowPress"); } public boolean onDown(MotionEvent e) { // Must return true to get matching events for this down event. return true; } public boolean onScroll(MotionEvent e1, MotionEvent e2, final float distanceX, float distanceY) { return super.onScroll(e1, e2, distanceX, distanceY); } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { // do something return super.onFling(e1, e2, velocityX, velocityY); } } 

如果您使用onTouchListener ,则不必使用onTouchListener 。 在onClickListener它所做的是获取触摸事件并检查事件操作并检测点击。 所以如果你想在onClick时做一些工作。 您可以通过过滤操作在onTouchListener此操作。

 public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { //this is touch } if (event.getAction() == MotionEvent.ACTION_UP) { //this is click } return false; } 
 @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_MOVE: layOutParams.x = initialX + (int) (event.getRawX() - initialTouchX); layOutParams.y = initialY + (int) (event.getRawY() - initialTouchY); break; case MotionEvent.ACTION_DOWN: initialX = layOutParams.x; initialY = layOutParams.y; initialTouchX = event.getRawX(); initialTouchY = event.getRawY(); if (initialTouchX == event.getRawX() && initialTouchY == event.getRawY()) { return false;// to handle Click } break; case MotionEvent.ACTION_UP: if (initialTouchX == event.getRawX() && initialTouchY == event.getRawY()) { return false;// to handle Click } break; } return true; } }; 

我同意jdx,如果你使用onTouchlistener你不需要使用onclicklistener和viceversa,如果你想触发button,图像,或textview点击事件,然后只需触发onClicklistener。 如果你想要一些animation,如拖动和旋转,然后使用ontouchlistener来获取所触摸的表面的坐标

 isMove = false; case MotionEvent.ACTION_DOWN: //Your stuff isMove = false; case MotionEvent.ACTION_UP: if (!isMove || (Xdiff < 10 && Ydiff < 10 ) { view.performClick; //The check for Xdiff <10 && YDiff< 10 because sometime elements moves a little even when you just click it } case MotionEvent.ACTION_MOVE: isMove = true; 

另一种方法是使用线程。 就是在Action_Down上启动一个线程来递增一个计数器。 在Action_UP的情况下:停止/中断线程。 寻找计数器,如果它小于2(说或阈值根据您的应用程序)或!isMove然后调用点击function

我们可以使用基于标志的实现。 在Action_Up中我们可以处理的滑动/拖动,并使标志为true并返回相同。 如果点击或在Action_Down中点击相同的句柄,并将该标志设置为false并返回。

  touchAndSwipe=false; switch(e.getAction()){ case MotionEvent.ACTION_MOVE: break; case MotionEvent.ACTION_DOWN: x1 = e.getX(); break; case MotionEvent.ACTION_UP: x2 = e.getX(); float diff= x2-x1; if(Math.abs(delta)>100){ // Swipe touchAndSwipe=true; }else{ touchAndSwipe=false; } break; } return touchAndSwipe; 

我已经能够在我正在构build的自定义键盘中一起实现OnClick和OnTouch。 你可以看看这个代码,并根据你的上下文来修改它,因为你没有包含一个代码示例。

如果您发布了您的代码样本,我可以修改这个样本来完成相同的结果供您使用。 上下文是Android开发的一切。 看看这个代码片段,看看是否有帮助。 否则张贴您自己的样本,我会做出修改并回复。

  View DefaultphaseLay() { LinearLayout mViewFirstPhase = (LinearLayout) getLayoutInflater().inflate(R.layout.layout_default_phase, parent); ksOne_btn_LiLay = (LinearLayout) mViewFirstPhase.findViewById(R.id.ksOne_btn_LiLay); ksOne_btn = (Button) mViewFirstPhase.findViewById(R.id.ksOne_btn); ksOne_btn.setOnClickListener(mCorkyListener); ksOne_btn.setFocusableInTouchMode(true); ksOne_btn.setFocusable(true); ksOne_btn.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { playClick(keyCode); //v.startAnimation(animScale); //key_sound.start(); xkeys_lay.setVisibility(View.GONE); numkeys_lay.setVisibility(View.GONE); if (Constants.HapticFeedbackConstant) { myVib.vibrate(Constants.vibration_duration); } } else if (event.getAction() == MotionEvent.ACTION_UP) { ksOne_btn.setFocusable(false); //Check This Added This In Attempt to Kill Selector on Action_Up //playClick(-100); //key_sound.pause(); } return false; } }); ChangeKeyBackgroundMehods.initChange_Key_Background(ksOne_btn_LiLay); ChangeFontStyle.initChange_fontStyle(ksOne_btn, getApplicationContext()); ChangeFont_size.initChange_fontSize(ksOne_btn, getApplicationContext()); 

这适用于alpha或数字输出types的上下文,如果事件正在发送或消耗一些其他上下文需要修改。