如何使用一个ImageButton Ontouch和Onclick?

在我的应用程序中,我想要发生两件事情。

  1. 当我触摸并拖动ImageButton时,它应该随着我的手指一起移动。

    我用这个OnTouchListener() ,它工作正常。

  2. 当我点击ImageButton时,它应该closures活动。

    我用这个OnClickListener() ,它也工作正常。

所以,这是我的问题。 每当我移动ImageButton OnTouchListenerOnClickListener被触发, ImageButton移动,当我释放button的时候, OnClickListener也会被触发。

如何在同一个button上使用ontouch和onclick监听器而不会相互干扰?

试试这个,它可以帮助你

不需要设置onClick()方法onTouch()将处理这两种情况。

 package com.example.demo; import android.app.Activity; import android.os.Bundle; import android.view.GestureDetector; import android.view.GestureDetector.SimpleOnGestureListener; import android.view.Menu; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.widget.ImageButton; public class MainActivity extends Activity { private GestureDetector gestureDetector; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); gestureDetector = new GestureDetector(this, new SingleTapConfirm()); ImageButton imageButton = (ImageButton) findViewById(R.id.img); imageButton.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View arg0, MotionEvent arg1) { if (gestureDetector.onTouchEvent(arg1)) { // single tap return true; } else { // your code for move and drag } return false; } }); } private class SingleTapConfirm extends SimpleOnGestureListener { @Override public boolean onSingleTapUp(MotionEvent event) { return true; } } } 

要让Click Listener OnLongPress ListenerDoubleClick ListenerOnLongPress ListenerSwipe Left Swipe RightSwipe Up Swipe DownView您需要setOnTouchListener 。 即

 view.setOnTouchListener(new OnSwipeTouchListener(MainActivity.this) { @Override public void onClick() { super.onClick(); // your on click here } @Override public void onDoubleClick() { super.onDoubleClick(); // your on onDoubleClick here } @Override public void onLongClick() { super.onLongClick(); // your on onLongClick here } @Override public void onSwipeUp() { super.onSwipeUp(); // your swipe up here } @Override public void onSwipeDown() { super.onSwipeDown(); // your swipe down here. } @Override public void onSwipeLeft() { super.onSwipeLeft(); // your swipe left here. } @Override public void onSwipeRight() { super.onSwipeRight(); // your swipe right here. } }); } 

为此,您需要实现OnTouchListener OnSwipeTouchListener类。

 public class OnSwipeTouchListener implements View.OnTouchListener { private GestureDetector gestureDetector; public OnSwipeTouchListener(Context c) { gestureDetector = new GestureDetector(c, new GestureListener()); } public boolean onTouch(final View view, final MotionEvent motionEvent) { return gestureDetector.onTouchEvent(motionEvent); } private final class GestureListener extends GestureDetector.SimpleOnGestureListener { private static final int SWIPE_THRESHOLD = 100; private static final int SWIPE_VELOCITY_THRESHOLD = 100; @Override public boolean onDown(MotionEvent e) { return true; } @Override public boolean onSingleTapUp(MotionEvent e) { onClick(); return super.onSingleTapUp(e); } @Override public boolean onDoubleTap(MotionEvent e) { onDoubleClick(); return super.onDoubleTap(e); } @Override public void onLongPress(MotionEvent e) { onLongClick(); super.onLongPress(e); } // Determines the fling velocity and then fires the appropriate swipe event accordingly @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { boolean result = false; try { float diffY = e2.getY() - e1.getY(); float diffX = e2.getX() - e1.getX(); if (Math.abs(diffX) > Math.abs(diffY)) { if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) { if (diffX > 0) { onSwipeRight(); } else { onSwipeLeft(); } } } else { if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) { if (diffY > 0) { onSwipeDown(); } else { onSwipeUp(); } } } } catch (Exception exception) { exception.printStackTrace(); } return result; } } public void onSwipeRight() { } public void onSwipeLeft() { } public void onSwipeUp() { } public void onSwipeDown() { } public void onClick() { } public void onDoubleClick() { } public void onLongClick() { } } 

onClick和OnTouch事件的问题是,当你点击(意图点击)它假定事件是OnTouch,因此OnClick从不被解释。 周围的工作

 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; 

我试图在我的项目中应用@Biraj解决scheme,它不工作 – 我已经注意到SimpleOnGestureListener扩展SimpleOnGestureListener应该覆盖onSingleTapConfirmed方法,但onDown 。 由于文件 :

如果从onDown()返回false,则默认情况下,GestureDetector.SimpleOnGestureListener会假设您要忽略手势的其余部分,并且GestureDetector.OnGestureListener的其他方法永远不会被调用

以下是复杂的解决scheme

 public class MainActivity extends Activity { private GestureDetector gestureDetector; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); gestureDetector = new GestureDetectorCompat(this, new SingleTapConfirm()); ImageButton imageButton = (ImageButton) findViewById(R.id.img); imageButton.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View arg0, MotionEvent arg1) { if (gestureDetector.onTouchEvent(arg1)) { // single tap return true; } else { // your code for move and drag } return false; } }); } private class SingleTapConfirm extends SimpleOnGestureListener { @Override public boolean onDown(MotionEvent e) { /*it needs to return true if we don't want to ignore rest of the gestures*/ return true; } @Override public boolean onSingleTapConfirmed(MotionEvent event) { return true; } } } 

我想,这种行为可能是由不同的GestureDetectorCompat引起的,但我会遵循文档 ,我将使用第二个:

您应尽可能使用支持库类,以提供与运行Android 1.6及更高版本的设备的兼容性

MainActivity代码中。

 public class OnSwipeTouchListener_imp extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_on_swipe_touch_listener); ImageView view = (ImageView)findViewById(R.id.view); view.setOnTouchListener(new OnSwipeTouchListener(OnSwipeTouchListener_imp.this) { @Override public void onClick() { super.onClick(); // your on click here Toast.makeText(getApplicationContext(),"onClick",Toast.LENGTH_SHORT).show(); } @Override public void onDoubleClick() { super.onDoubleClick(); // your on onDoubleClick here } @Override public void onLongClick() { super.onLongClick(); // your on onLongClick here } @Override public void onSwipeUp() { super.onSwipeUp(); // your swipe up here } @Override public void onSwipeDown() { super.onSwipeDown(); // your swipe down here. } @Override public void onSwipeLeft() { super.onSwipeLeft(); // your swipe left here. Toast.makeText(getApplicationContext(),"onSwipeLeft",Toast.LENGTH_SHORT).show(); } @Override public void onSwipeRight() { super.onSwipeRight(); // your swipe right here. Toast.makeText(getApplicationContext(),"onSwipeRight",Toast.LENGTH_SHORT).show(); } }); } } 

然后创build一个OnSwipeTouchListener java类。

 public class OnSwipeTouchListener implements View.OnTouchListener { private GestureDetector gestureDetector; public OnSwipeTouchListener(Context c) { gestureDetector = new GestureDetector(c, new GestureListener()); } public boolean onTouch(final View view, final MotionEvent motionEvent) { return gestureDetector.onTouchEvent(motionEvent); } private final class GestureListener extends GestureDetector.SimpleOnGestureListener { private static final int SWIPE_THRESHOLD = 100; private static final int SWIPE_VELOCITY_THRESHOLD = 100; @Override public boolean onDown(MotionEvent e) { return true; } @Override public boolean onSingleTapUp(MotionEvent e) { onClick(); return super.onSingleTapUp(e); } @Override public boolean onDoubleTap(MotionEvent e) { onDoubleClick(); return super.onDoubleTap(e); } @Override public void onLongPress(MotionEvent e) { onLongClick(); super.onLongPress(e); } // Determines the fling velocity and then fires the appropriate swipe event accordingly @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { boolean result = false; try { float diffY = e2.getY() - e1.getY(); float diffX = e2.getX() - e1.getX(); if (Math.abs(diffX) > Math.abs(diffY)) { if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) { if (diffX > 0) { onSwipeRight(); } else { onSwipeLeft(); } } } else { if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) { if (diffY > 0) { onSwipeDown(); } else { onSwipeUp(); } } } } catch (Exception exception) { exception.printStackTrace(); } return result; } } public void onSwipeRight() { } public void onSwipeLeft() { } public void onSwipeUp() { } public void onSwipeDown() { } public void onClick() { } public void onDoubleClick() { } public void onLongClick() { } } 

希望这光ü:)

也许你可以使用布尔值。

让我们说布尔isMoving = false;

 public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_MOVE: isMoving = true; // implement your move codes break; case MotionEvent.ACTION_UP: isMoving = false; break; default: break; } 

然后在你的onclick方法检查布尔值。 如果它是假的,那么执行点击操作,如果真的…不采取行动。

 public void onClick(View arg0) { switch (arg0.getId()) { case R.id.imagebutton: if(!isMoving) { //code for on click here } default: break; } } 

Clieck Listener事件; 如果在您的组件边界内执行动作和动作,则比调用onclicklistener。 因此onclick事件激活与触摸检测。 您只能设置onTouchListener,并在组件中的动作和动作开始时接收点击事件。

声明一个私有variables,如: boolean hasMoved = false;

当图像button开始移动时,设置hasMoved = true

在你的OnClickListener只有if(!hasMoved)执行代码 – 意味着只有当button没有移动时才能在点击function上执行。 设置hasMoved = false; 之后

只需使用布尔字段,并在触发OnTouchListener时将其设置为true值。 之后,当OnClickListener想触发你将检查布尔字段,如果真的不要在你的onClickListener中做任何事情。

  private blnTouch = false; private OnTouchListener btnOnTouchListener = new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub if (event.getAction()==MotionEvent.ACTION_DOWN){ blnOnTouch = true; } if (event.getAction()==MotionEvent.ACTION_UP){ blnOnTouch = false; } } }; private OnClickListener btnOnClickListener = new OnClickListener() { @Override public void onClick(View arg0) { if (blnOnTouch){ // Do Your OnClickJob Here without touch and move } } };