как использовать Ontouch и Onclick для ImageButton?
в моем приложении я хочу, чтобы произошли две вещи.
-
когда я касаюсь и перетаскиваю ImageButton, он должен двигаться вместе с моим пальцем.
Я
OnTouchListener()
для этого и работает отлично. -
когда я нажимаю ImageButton, он должен закрыть активность.
Я
OnClickListener()
для этого и работает отлично.
Итак, вот моя проблема. всякий раз, когда я двигаю ImageButton
OnTouchListener
- это tirggered а то ImageButton
движется OnClickListener
также срабатывает в конце, когда я отпускаю кнопку от перемещения.
как использовать ontouch и onclick слушателей на той же кнопке, не мешая друг другу?
9 ответов:
попробуйте это, это может помочь вам
нет необходимости устанавливать
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
,DoubleClick Listener
,OnLongPress Listener
,Swipe Left
,Swipe Right
,Swipe Up
,Swipe Down
on SingleView
вам нужно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. } }); }
для этого вам понадобится
OnSwipeTouchListener
класс, реализующийOnTouchListener
.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 event заключается в том, что в тот момент, когда вы нажимаете(с намерением щелкнуть), он предполагает, что событие 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 в своем проекте, и это не сработало - я заметил, что расширение
SimpleOnGestureListener
должен не только переопределятьonSingleTapConfirmed
способ, ноonDown
как хорошо. Из-за документация:если вы возвращаете false из onDown (), как GestureDetector.SimpleOnGestureListener делает по умолчанию, система предполагает, что вы хотите игнорировать остальную часть жеста и другие методы GestureDetector.OnGestureListener никогда не получить называется
Ниже приводится комплексное решение:
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 и выше
может быть, вы можете работать с boolean.
допустим Boolean 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 проверьте логическое значение. Если это значение равно false, то выполните действие щелчка, если true ... не выступать.
public void onClick(View arg0) { switch (arg0.getId()) { case R.id.imagebutton: if(!isMoving) { //code for on click here } default: break; } }
на
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(); } }); } }
затем создать
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() { } }
надеюсь, что это огни u:)
Clieck Listener event;если actiondown и action up в ваших компонентах ограничиваются, чем вызов onclicklistener. Таким образом, событие onclick активируется с сенсорным обнаружением. Вы можете только установить onTouchListener и получать события щелчка, если действие вверх и действие вниз в начальной позиции компонентов.
объявить закрытую переменную типа:
boolean hasMoved = false;
когда кнопка изображения начнет двигаться, установите
hasMoved = true
в своем
OnClickListener
выполнить код толькоif(!hasMoved)
-- означает выполнение функции щелчка только в том случае, если кнопка не перемещена. НаборhasMoved = false;
после
просто используйте логическое поле и установите его в значение true, когда ваш OnTouchListener запускается. после этого, когда OnClickListener хочет вызвать вы будете проверять логическое поле и если true ничего не действует в вашем 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 } } };