Я делаю меню, где элементы должны реагировать на два типа событий:Android - Ручка нажмите и проведите пальцем по пунктам ListView
OnClick
Если пользователь нажимает на элемент, он должен начать работу. Каждая кнопка запускает другое действие.OnFling
Когда пользователь пойло элемент справа налево, появится его название. Каждый элемент имеет другое имя, и имя будет отображаться только в позиции, которая была пробита.
Я пробовал много разных вещей, искал много учебников и вопросов здесь, в StackOverflow, но я не мог найти достойный ответ, а моя реализация по-прежнему бедна.
То, что я делаю прямо сейчас устанавливая OnClick
ручки для каждого элемента в методе getView
моего пользовательский адаптер и установкой gestureListener на моем ListView и обработку метода onFling
, но он не действует, как ожидался: большинство из раз, когда я пытаюсь ударить и жест обрабатывается как щелчок ...
Я знаю, что я мог бы использовать реализацию как this, но я думаю, что я не могу использовать трюк события onTouch в этом случае, потому что мне нужно посмотреть позицию, чтобы я мог обрабатывать, какую деятельность следует запускать (onTouch/click) или которая TextView
shou ld становятся видимыми.
Вот фрагменты кода, которые у меня есть до сих пор:
final GestureDetector gestureDetector = new GestureDetector(
new GestureListener());
lvMenu.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(final View view, final MotionEvent event) {
if (gestureDetector.onTouchEvent(event)) {
return false;
}
return true;
}
});
Внутренний класс:
class GestureListener extends SimpleOnGestureListener {
protected MotionEvent mLastOnDownEvent = null;
@Override
public boolean onDown(final MotionEvent e) {
return true;
}
@Override
public boolean onFling(final MotionEvent e1, final MotionEvent e2,
final float velocityX, final float velocityY) {
Log.d("OnFling", "Called");
final int SWIPE_MIN_DISTANCE = 20;
final int SWIPE_MAX_OFF_PATH = 250;
final int SWIPE_THRESHOLD_VELOCITY = 200;
try {
if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH) {
return false;
}
if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE
&& Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
Log.i("A", "Right to Left");
} else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
&& Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
Log.i("B", "Left to Right");
}
} catch (final Exception e) {
// nothing
}
return super.onFling(e1, e2, velocityX, velocityY);
}
}
И onClick()
метод внутри моего пользовательского адаптера:
public void onClick(final View v) {
Intent i = null;
switch (position) {
case 0:
i = new Intent(parent.getContext(),
ProfileActivity.class);
break;
case 1:
i = new Intent(parent.getContext(),
CatalogActivity.class);
break;
case 2:
i = new Intent(parent.getContext(), GuideActivity.class);
break;
case 3:
i = new Intent(parent.getContext(),
EventsActivity.class);
break;
default:
Log.d("MenuActivity", "Switch default case.");
break;
}
if (i != null) {
parent.getContext().startActivity(i);
}
}
Спасибо)
EDIT 1: Теперь я пытаюсь установить OnTouchListener для каждого представления в моем пользовательском адаптере. Но он не работает ... Я не могу понять причину.
Это, как я устанавливаю вверх TouchListener:
convertView.setOnTouchListener(new MenuGestureHandler() {
@Override
public boolean onSwipeRight() {
Log.d("Swipe Right", "OK!");
return true;
}
@Override
public void onClick() {
Log.d("Click", "OK!");
}
});
И это класс (с каким-то бесполезным кодом, как swipeUp, swipeDown):
public class MenuGestureHandler implements OnTouchListener {
GestureDetector gestureDetector = new GestureDetector(new GestureListener());
@Override
public boolean onTouch(final View v, final MotionEvent event) {
return gestureDetector.onTouchEvent(event);
}
private final class GestureListener extends SimpleOnGestureListener {
private static final int SWIPE_THRESHOLD = 100;
private static final int SWIPE_VELOCITY_THRESHOLD = 100;
@Override
public boolean onSingleTapConfirmed(final MotionEvent e) {
onClick(); // my method
return super.onSingleTapConfirmed(e);
}
@Override
public boolean onFling(final MotionEvent e1, final MotionEvent e2,
final float velocityX, final float velocityY) {
boolean result = false;
try {
final float diffY = e2.getY() - e1.getY();
final 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) {
result = onSwipeRight();
} else {
result = onSwipeLeft();
}
}
} else {
if (Math.abs(diffY) > SWIPE_THRESHOLD
&& Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
if (diffY > 0) {
result = onSwipeBottom();
} else {
result = onSwipeTop();
}
}
}
} catch (final Exception exception) {
exception.printStackTrace();
}
return result;
}
}
public boolean onSwipeRight() {
return false;
}
public boolean onSwipeLeft() {
return false;
}
public void onClick() {
}
public boolean onSwipeTop() {
return false;
}
public boolean onSwipeBottom() {
return false;
}
EDIT 2 я мог заставить его работать, просто переопределив метод onDown()
в моем классе GestureListener и установив его, чтобы он всегда возвращал true. Я действительно не понимаю, зачем мне это нужно, но похоже, что он работает сейчас!
Хорошо, прекрасно. Теперь я понимаю проблему ... Но я не могу прикрепить OnTouchListener к каждому элементу, я не знаю почему! Это просто не работает ... Можете ли вы мне помочь? Я редактировал свой пост с самым новым кодом. Огромное спасибо. –