Android: пользовательский просмотр onClickEvent с X & Y-местоположениями
У меня есть пользовательский вид, и я хочу получить координаты X и Y клика пользователя. Я обнаружил, что могу получить координаты только от onTouchEvent, а onClickEvent не будет стрелять, если у меня есть onTouchEvent. К сожалению, onTouchEvent срабатывает, когда пользователь перетаскивает экран, а также щелкает.
Я пытался различать эти два, но я все еще получаю срабатывание кода, когда я перетаскиваю:
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN) {
//fires on drag and click
Я посмотрел на это но, как я уже упоминал выше, я не думаю, что решение там будет работать, так как я не могу заставить события onClick и onTouch работать одновременно. Может быть, я делаю что-то не так в этом отношении, есть ли нормальный способ борьбы с захватом пользовательского ввода на пользовательских событиях? Должен ли я быть в состоянии использовать события onClick и onTouch одновременно?
Спасибо, Мартин
6 ответов:
Теперь, я не знаю о onTouchEvent короткого замыкания onClick, и я не знаю, может быть, вам нужно установить
android:clickable
в true (илиsetClickable(true)
). Но, если вы не можете заставить его работать чисто, вы можете использовать логическое значение в onTouchEvent, чтобы имитировать обнаружение щелчка, если все остальное не удается. в ACTION_DOWN установите его в true (isClicking или что-то вроде этого), в ACTION_MOVE установите его в false (потому что пользователь перетаскивает, поэтому не щелкает), а затем в ACTION_UP вы можете проверить его. Если это правда, то это означает, что пользователь придавил, но не потащил. Это банально, но если вы не можете заставить onClick работать, это в основном одно и то же.
Что вы возвращаете в конце вашего onTouchEvent? Согласно документации, возврат true означает "событие было полностью обработано, больше ничего с ним не делать", в то время как возврат false означает, что система продолжит обработку. Я не проверял это с вашей конкретной ситуацией, но это предполагает, что возвращение false может сработать. Это заставило бы систему продолжить обработку касания / щелчка и отправить его в следующий вид "снизу".
Если это не сработает, то я пока не могу подумайте о лучшем решении, чем делать что-то подобное тому, что предложил Рич. Вы можете сделать что-то вроде получения времени на ACTION_DOWN, а затем на ACTION_UP, сравнить время, которое прошло. Если он меньше 100 миллисекунд,то его следует интерпретировать как щелчок. Затем вы можете запустить любой код, который вы хотите поместить в свой прослушиватель кликов.
Например, вот как вы можете это закодировать:
long touchDownTime; // This has to be a class field so that it persists // between calls to onTouchEvent public boolean onTouchEvent(MotioNEvent event){ boolean handled = false; int action = event.getAction(); switch (action){ case MotionEvent.ACTION_DOWN: touchDownTime = SystemClock.elapsedRealtime(); break; case MotionEvent.ACTION_UP: if (SystemClock.elapsedRealtime() - touchDownTime <= 100){ int x = event.getX(); //or event.getRawX(); int y = event.getY(); performYourClick(x, y); handled = true; } break; } return handled; }
Примечание: я на самом деле не тестировал этот код, так что, возможно, я сделал некоторые синтаксические ошибки. Хотя общая идея все равно должна быть прекрасной.
К вашему сведению, в моих тестах похоже, что onTouch переопределяет onClick для представления, независимо от того, возвращает ли onTouch true или false.
- Frink
Я смог решить эту проблему
Я создал пользовательский вид public class QuestionBuilderView extends View
В файле макета
< com.example.android.view.QuestionBuilderView android:id="@+id/questionbuilderview" android:layout_width="fill_parent" android:layout_height="wrap_content" />
В основном действии попробуйте вызвать пользовательский вид и установить прослушиватель событий Onclick / On Touch на вид
View questionBuilder = findViewById(R.id.questionbuilderview); questionBuilder.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent event) { // TODO Auto-generated method stub float touched_x = event.getX(); float touched_y = event.getY(); Toast.makeText(getApplicationContext(), " "+touched_x +","+touched_y, Toast.LENGTH_LONG).show(); // int action = event.getAction(); return true; }
Я думаю, ты должен позвонить супер.onTouchEvent (событие), потому что в этом методе обнаружен щелчок.
Вы должны использовать
GestureDetector
. ПодклассGestureDetector.SimpleOnGestureListener
и переопределение методаonDown(MotionEvent event)
для возврата true. Затем переопределитеonSingleTapConfirmed
. Передайте прослушиватель конструкторуGestureDetector
. Затем вызовитеsetOnDoubleTapListener
с этим слушателем в качестве параметра:// in your view class constructor GestureDetector.SimpleOnGestureListener listener = new GestureDetector.SimpleOnGestureListener() { @Override public boolean onDown(MotionEvent e) { return true; } @Override public boolean onSingleTapConfirmed(MotionEvent e) { // do whatever you want return true; } }; mDetector = new GestureDetector(getContext(), listener); mDetector.setOnDoubleTapListener(listener);
Затем вы можете передать
MotionEvent
s детектору:@Override public boolean onTouchEvent(MotionEvent event) { return mDetector.onTouchEvent(event); }