android - ejemplo - OnTouch funciona, pero OnClickListener no?
onlongclick android (8)
Creé un widget / control que puedo reutilizar lo que creé extendiendo RelativeLayout
. Luego, en una de mis Actividades, creé un montón de estos widgets en un bucle. Sin embargo, me encontré con un problema cuando quería que cada widget respondiera a un clic.
Encontré que la configuración de OnTouchListener
funciona:
this.setOnTouchListener(new OnTouchListener(){
public boolean onTouch(View arg0, MotionEvent arg1) {
//Triggers debug message
}
});
pero OnClickListener
no lo hace:
this.setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
//Doesn''t trigger debug message
}
});
¿Por qué es esto?
¿Está devolviendo el valor onTouch booleano correctamente?
De los documentos:
onTouch () : devuelve un valor booleano para indicar si su oyente consume este evento. Lo importante es que este evento puede tener múltiples acciones que se siguen unas a otras. Por lo tanto, si devuelve falso cuando se recibe el evento de acción descendente, indica que no ha consumido el evento y que tampoco está interesado en acciones posteriores de este evento. Por lo tanto, no se le llamará para ninguna otra acción dentro del evento, como un gesto con el dedo o el evento eventual de acción ascendente.
EDITAR
Encontré la solución en esta question y la probé yo mismo.
return super.onTouchEvent(event);
usar este return super.onTouchEvent(event);
en su código onTouchEvent. Después de agregar esto, OnClickListener comenzó a funcionar.
Aquí hay algunas cosas que debe verificar para asegurarse de que se pueda hacer clic en sus vistas:
View.setClickable()
View.setEnabled()
View.setFocusable()
View.setFocusableInTouchMode()
Dependiendo del comportamiento exacto que espere obtener, deberá configurar uno o más de ellos. Dado que está recibiendo eventos onTouch, mi conjetura es que necesita configurarClickable. Pero tendría que ver el código de creación de la vista para estar seguro.
Cuando necesite los eventos onClick y onTouch en la misma vista, use un GestureDetector .
Debe asegurarse de que el TouchListener no esté "consumiendo" el evento táctil. Si devuelve true desde el método onTouch()
, Android lo considerará consumido y no lo pasará a otros controladores táctiles (que supongo que incluirán el ClickListener).
Deberías hacer:
this.setOnTouchListener(new OnTouchListener(){
public boolean onTouch(View arg0, MotionEvent arg1) {
//Triggers debug message
return false;
}
});
Para realizar este retorno falso en tu onTouch()
esta manera:
this.setOnTouchListener(new OnTouchListener(){
public boolean onTouch(View arg0, MotionEvent arg1) {
return false;
}
});
Puede implementar un onClickListener a través de 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;
}
});
Si anula el método onMotionEvent () por alguna razón y necesita devolver verdadero / falso en ese caso, puede activar manualmente la devolución de llamada OnClickListener () llamando a this.performClick () dentro del onMotionEvent () anulado justo antes de que devuelva true /falso.
Si has intentado devolver el falso:
this.setOnTouchListener(new OnTouchListener(){
public boolean onTouch(View arg0, MotionEvent arg1) {
return false;
}
});
y no funcionó, pruebe esta solución si está utilizando ScrollView. Agregue un LinearLayout dentro de ScrollView. Establecer que se pueda hacer clic en true en él. Llame a setOnClickListener y setOnTouchListener desde LinearLayout.
<ScrollView
android:id="@+id/scrollview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:scrollbarStyle="outsideOverlay">
<LinearLayout
android:id="@+id/linearlayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:gravity="center_vertical"
android:orientation="vertical">
<content... />
</LinearLayout>
</ScrollView>
LinearLayout linearlayout = findViewById(R.id.linearlayout);
linearlayout.setOnClickListener...
linearlayout.setOnTouchListener...