OnTouch работает, но OnClickListener этого не делает?
Я создал виджет/элемент управления, который я могу повторно использовать, который я создал, расширяя RelativeLayout
. Затем в одной из моих работ я создал кучу этих виджетов в цикле. Однако у меня возникла проблема, когда я хотел, чтобы каждый виджет ответил на клик.
Я обнаружил, что настройка OnTouchListener
работает:
this.setOnTouchListener(new OnTouchListener(){
public boolean onTouch(View arg0, MotionEvent arg1) {
//Triggers debug message
}
});
но OnClickListener
не:
this.setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
//Doesn't trigger debug message
}
});
Почему это?
Ответы
Ответ 1
Вот несколько вещей, которые нужно проверить, чтобы убедиться, что ваши взгляды доступны для просмотра:
View.setClickable()
View.setEnabled()
View.setFocusable()
View.setFocusableInTouchMode()
В зависимости от точного поведения, которое вы надеетесь получить, вам нужно установить один или несколько из них. Поскольку вы получаете onTouch-события, я предполагаю, что вам нужно установитьClickable. Но я должен был бы видеть код создания представления.
Ответ 2
Вы должны убедиться, что TouchListener не "поглощает" событие касания. Если вы вернете true из метода onTouch()
, Android рассмотрит его потребление и не передаст его другим другим обработчикам сенсорных обработок (который, как я предполагаю, будет включать ClickListener).
Вам следует:
this.setOnTouchListener(new OnTouchListener(){
public boolean onTouch(View arg0, MotionEvent arg1) {
//Triggers debug message
return false;
}
});
Ответ 3
Правильно ли вы возвращаете значение boolean onTouch?
Из документов:
onTouch() - возвращает логическое значение, указывающее ли ваш слушатель потребляет это мероприятие. Важно то, что это событие может иметь несколько действий которые следуют друг за другом. Итак, если вы return false, когда действие вниз событие получено, вы указываете, что вы не воспользовались событием и также не заинтересованы в последующих действия этого события. Таким образом, вы не будет вызвана для каких-либо других действий в рамках мероприятия, таких как жест пальца или, возможно, вверх событие действия.
ИЗМЕНИТЬ
Нашел решение в этом question и попробовал сам.
Вам нужно использовать этот return super.onTouchEvent(event);
в вашем коде onTouchEvent. После добавления этого OnClickListener начал работать.
Ответ 4
Чтобы выполнить это, верните false в свой onTouch()
следующим образом:
this.setOnTouchListener(new OnTouchListener(){
public boolean onTouch(View arg0, MotionEvent arg1) {
return false;
}
});
Ответ 5
Вы можете выполнить onClickListener через onTouchListener:
webView.setOnTouchListener(new View.OnTouchListener() {
public final static int FINGER_RELEASED = 0;
public final static int FINGER_TOUCHED = 1;
public final static int FINGER_DRAGGING = 2;
public final static int FINGER_UNDEFINED = 3;
private int fingerState = FINGER_RELEASED;
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
if (fingerState == FINGER_RELEASED) fingerState = FINGER_TOUCHED;
else fingerState = FINGER_UNDEFINED;
break;
case MotionEvent.ACTION_UP:
if(fingerState != FINGER_DRAGGING) {
fingerState = FINGER_RELEASED;
// Your onClick codes
}
else if (fingerState == FINGER_DRAGGING) fingerState = FINGER_RELEASED;
else fingerState = FINGER_UNDEFINED;
break;
case MotionEvent.ACTION_MOVE:
if (fingerState == FINGER_TOUCHED || fingerState == FINGER_DRAGGING) fingerState = FINGER_DRAGGING;
else fingerState = FINGER_UNDEFINED;
break;
default:
fingerState = FINGER_UNDEFINED;
}
return false;
}
});
Ответ 6
Если вы переопределите метод onMotionEvent() по какой-либо причине, и вам нужно вернуть true/false в этом случае, вы можете вручную вызвать обратный вызов OnClickListener(), вызвав this.performClick() внутри переопределенного onMotionEvent() непосредственно перед вы возвращаете true/false.
Ответ 7
Если вам нужны как события onClick, так и onTouch на одном и том же представлении, используйте GestureDetector.