Pregunta

Tengo una aplicación que necesita manejo de eventos de manera inusual.

Para mi pregunta, permítanme explicar primero un caso simple de que el sistema actual de manejo de eventos de Android no me queda bien.

Suponiendo que tengo un framelayout (que llamaré a Viewswiper desde ahora) que todas las vistas agregadas en él son Match_Parent X Match_parent (que llamaré PageView), maneja los eventos traduciendo la vista real y reemplazarla en función de la dirección de moverse. Este componente que ya he hecho y funcionando correctamente ( Uso de la animación para deslizar las vistas ).

Pero el problema está en esa vista de página que agrego encima, en el caso de ImageViews que devuelvan falsos en su OnTouchEvent, el ViewSwiper manejará los eventos y dejará que otro PageView ingrese a la pantalla, pero si agrego una vista de desplazamiento sobre eso, todo el Los eventos serán consumidos por el pergamino y el ViewSwiper no tendrá la oportunidad de reemplazar el PageView.

Así que descubrí que devolver el falso onuchevent de ScrollView, el padre puede asumir que son eventos, escribí esta subclase de ScrollView para probarlo:

public class ScrollViewVertical extends ScrollView {
    public ScrollViewVertical(Context context) {
        super(context);
        setOverScrollMode(OVER_SCROLL_ALWAYS);
        setVerticalScrollBarEnabled(false);
    }

    public boolean onTouchEvent(MotionEvent evt) {
        super.onTouchEvent(evt);
        return false;
    }
}

Pero devolverse False haz más eventos para ser enviados a los padres, pero necesito estos eventos para desplazamiento vertical, por lo que tengo la idea de devolver falses solo si el usuario se mueve horizontal, así es como se ve mi código:

public class ScrollViewVertical extends ScrollView {
    private MovementTracker moveTracker;
    public ScrollViewVertical(Context context) {
        super(context);
        setOverScrollMode(OVER_SCROLL_ALWAYS);
        setVerticalScrollBarEnabled(false);
        moveTracker = new MovementTracker();
    }
    public boolean onTouchEvent(MotionEvent evt) {
        if (moveTracker.track(evt))
            if (moveTracker.getDirection() == Direction.HORIZONTAL)
                return false;

        return super.onTouchEvent(evt);
    }
}

PD: MovimientoTracker devuelve True On Track () después de algunos eventos y contará en qué dirección se está moviendo el usuario.

Pero en ese caso, ScrollView sigue recibiendo eventos ya que se devuelve cierto en los primeros eventos.

Cualquier idea sobre cómo puedo manejar los eventos en ViewSwiper cuando es niño devuelve falso (incluso si se devuelven algunos trues).

PD: Puedo dar más información sobre esto si es necesario y aceptar diferentes soluciones también.

Según las respuestas, probé lo siguiente:

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    onTouchEvent(ev);
    return intercept;
}

public boolean onTouchEvent(MotionEvent evt) {
    boolean x = super.onTouchEvent(evt);

    if (moveTracker.track(evt)) {
        intercept = moveTracker.getDirection() != Direction.VERTICAL;
        if (!intercept)
            getParent().requestDisallowInterceptTouchEvent(false);
    }

    return x;
}

Aún nada.

¿Fue útil?

Solución

Prueba esto en onTouchEvent() del ScrollView

     //if (evt.getAction() == MotionEvent.ACTION_MOVE) {
    if (moveTracker.track(evt)){
       if (moveTracker.getDirection() == Direction.VERTICAL){
          //Or the direction you want the scrollview keep moving
          getParent().requestDisallowInterceptTouchEvent(true);

            }
        } 
 return true;

Actualizar

Pruebe lo siguiente en el ScrollView personalizado

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
super.dispatchTouchEvent(ev);
    return false;
}

Y nada más

De esta manera, supongo que MotionEvent funcionará en ambas vistas. Y dado que no entran en conflicto (uno es vertical, el otro es horizontal) esto podría funcionar

Otros consejos

Basado en la respuesta de Weakwire, llegué a la siguiente solución:

En Viewswiper

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if(!super.dispatchTouchEvent(ev))
            onTouchEvent(ev);
        return true;
    }

Y en ScrollHorizontal devuelve falso en DispatchTouchEvent cuando ya no necesito.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top