Lasciate genitore View assumere MotionEvents se i rendimenti bambino falso
-
27-10-2019 - |
Domanda
Ho un'applicazione che evento necessità di movimentazione in un modo insolito.
Per la mia domanda, vorrei prima spiegare un semplice caso che l'attuale sistema di gestione degli eventi di Android non lo fanno adatta per me.
Supponendo che ho un FrameLayout (che chiamerò ViewSwiper fin da ora) che tutte le opinioni aggiunte su di esso sono MATCH_PARENT X MATCH_PARENT (che chiamerò PageView), è gestisce gli eventi traducendo l'attuale vista e sostituirlo base sulla direzione del movimento. Questo mi componente già fatto e il lavoro correttamente ( Utilizzando animazione a vista magnetiche ).
Ma il problema è su quella PageView aggiungo su di esso, in caso di ImageViews che return false su di essa l'onTouchEvent, il ViewSwiper gestirà gli eventi e lasciare che un altro PageView accedere alla schermata, ma se aggiungo una ScrollView su quel , tutti gli eventi saranno consumati dalla Scorrere e la ViewSwiper non avrà la possibilità di sostituire il PageView.
Così ho capito che il ritorno falsa onTouchEvent del ScrollView il genitore può supporre che di eventi, ho scritto questo sotto-classe di ScrollView per testarlo:
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;
}
}
Ma tornando falso effettuare ulteriori eventi per ottenere inviati al genitore, ma ho bisogno di questi eventi per scorrimento verticale, in modo da avere l'idea per restituire solo falses se l'utente si stanno muovendo ORIZZONTALE, questo è ciò che il mio aspetto codice come:
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);
}
}
PS:. MovementTracker si torna in pista vere (), dopo alcuni eventi e dire della direzione in cui l'utente è in movimento
Ma in questo caso, lo ScrollView continuare a ricevere gli eventi dal momento che è vero rendimenti sui primi eventi.
Tutte le idee su come posso gestire gli eventi in ViewSwiper quando è bambino restituisce false (anche se alcune Trues vengono restituiti).
PS:. Mi può dare maggiori informazioni su questo, se necessario, e ad accettare soluzioni differenti anche
Sulla base delle risposte ho provato la seguente:
@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;
}
Ancora nulla.
Soluzione
provare questo in 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;
Aggiorna
Si prega di tentare di risolverli al costume Scrollview
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
super.dispatchTouchEvent(ev);
return false;
}
E nient'altro
In questo modo Suppongo che il MotionEvent si esibiranno su entrambi i punti di vista. E dal momento che non sono in conflitto (uno è verticale l'altro è orizzontale) questo potrebbe funzionare
Altri suggerimenti
In base alla risposta da weakwire, sono venuto alla soluzione seguente:
On ViewSwiper
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if(!super.dispatchTouchEvent(ev))
onTouchEvent(ev);
return true;
}
E sul ScrollHorizontal ho return false su dispatchTouchEvent quando non ho bisogno quindi più.