如何使用一个ImageButton Ontouch和Onclick?
在我的应用程序中,我想要发生两件事情。
-
当我触摸并拖动ImageButton时,它应该随着我的手指一起移动。
我用这个
OnTouchListener()
,它工作正常。 -
当我点击ImageButton时,它应该closures活动。
我用这个
OnClickListener()
,它也工作正常。
所以,这是我的问题。 每当我移动ImageButton
OnTouchListener
, OnClickListener
被触发, 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 Listener
, DoubleClick Listener
, OnLongPress Listener
, Swipe Left
Swipe Right
, Swipe Up
Swipe Down
单View
您需要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 } } };