2014-10-14 17 views
7

LayoutCome acquisire gli eventi onTouch su due viste sovrapposte?

! * Container is a relative layout contains two custom views: OuterView1 and InnerView2 * Outer View1 is a custom view, matching the parent’s size (full screen) * Inner View2 is also a custom view, laid on top of OuterView1 overlapping it.

  • Container è un layout relativo contiene due visualizzazioni personalizzate: OuterView1 e InnerView2
  • esterno Visualizzazione1 è una visualizzazione personalizzata, corrispondenti dimensioni del genitore (schermo intero)
  • interno View2 è anche una visualizzazione personalizzata, di cui in cima a OuterView1 che si sovrappone a esso.

Su OuterView1 e InnerView2, voglio acquisire questi eventi di tocco suSingleTapConfirmed() e onFling(). L'area in cui OuterView1 e InnerView2 si sovrappongono, voglio che il controllo sia passato per toccare i metodi evento di entrambe le viste.

ho provato questo:

classe Container

@Override 
    public boolean onInterceptTouchEvent(MotionEvent ev) { 
     outerView1.onTouchEvent(ev); 
     innerView2.onTouchEvent(ev); 
     return false; 
    } 

classe OuterView1

@Override 
    public boolean onTouchEvent(MotionEvent event) { 
     gesture.onTouchEvent(event); 
     return true; 
    } 

gesto è un esempio di GestureDetector.SimpleOnGestureListener con le dichiarazioni di registro per onDown(), onFling() e metodi onSingleTapConfirmed()

InnerView2 clas s

@Override 
    public boolean onTouchEvent(MotionEvent event) { 
     gesture.onTouchEvent(event); 
     return true; 
    } 

gesto è un esempio di GestureDetector.SimpleOnGestureListener con le dichiarazioni di registro per onDown(), onFling() e onSingleTapConfirmed() metodi

Con questo approccio, ho sempre arrivare richiamata in onDown() i metodi di entrambi i punti di vista. Ma io non vedo un comportamento coerente sul onSingleTapConfirmed() e onFling() metodi

Quando ho sfruttato nel cerchio rosso (nello screenshot) tre volte e ho ottenuto tre diversi comportamenti

  • First provare (comportamento desiderato)

    10-14 09:03:14.155: I/OuterView1(27776): OuterView1.onDown() 
    10-14 09:03:14.155: I/InnerView2(27776): InnerView2.onDown() 
    10-14 09:03:14.155: W/GestureDetector(27776): [pen gesture] isConsideredDoubleTap - timeout 
    10-14 09:03:14.155: I/InnerView2(27776): InnerView2.onDown() 
    10-14 09:03:14.460: I/OuterView1(27776): OuterView1.onSingleTapConfirmed() 
    10-14 09:03:14.460: I/InnerView2(27776): InnerView2.onSingleTapConfirmed() 
    
  • secondo tentativo (un solo sguardo si onSingleTapConfirmed())

    10-14 09:04:11.615: I/OuterView1(27776): OuterView1.onDown() 
    10-14 09:04:11.615: I/InnerView2(27776): InnerView2.onDown() 
    10-14 09:04:11.615: W/GestureDetector(27776): [pen gesture] isConsideredDoubleTap - timeout 
    10-14 09:04:11.615: I/InnerView2(27776): InnerView2.onDown() 
    10-14 09:04:11.915: I/OuterView1(27776): OuterView1.onSingleTapConfirmed() 
    
  • terzo tentativo (Un punto di vista ottiene onFling() e un altro viene onSingleTapConfirmed())

    10-14 09:04:04.180: I/OuterView1(27776): OuterView1.onDown() 
    10-14 09:04:04.180: I/InnerView2(27776): InnerView2.onDown() 
    10-14 09:04:04.180: W/GestureDetector(27776): [pen gesture] isConsideredDoubleTap - timeout 
    10-14 09:04:04.180: I/InnerView2(27776): InnerView2.onDown() 
    10-14 09:04:04.255: I/InnerView2(27776): InnerView2.onFling() 
    10-14 09:04:04.480: I/OuterView1(27776): OuterView1.onSingleTapConfirmed() 
    

Potresti aiutarmi a catturare gli eventi tocco su entrambi i OuterView1 e InnerView2?

risposta

9

Pertanto, in caso di visualizzazioni sovrapposte, gli eventi tattili vengono inviati dal bambino più in alto a quello precedente, quindi un altro dietro al secondo figlio e così via. Tuttavia, se il bambino più in alto dovesse consumare l'evento tattile (ovvero gestirlo al ricevimento), le visualizzazioni al di sotto di quella vista non riceveranno gli eventi di tocco.

Se onTouchEvent restituisce "true", indica al gestore di visualizzazione che ha gestito il tocco e non desidera che l'evento venga inviato ad altre viste. Se vuoi che la vista sotto quella vista venga anche toccata, allora vuoi restituire 'false' da onTouchEvent per la prima vista, nel tuo caso Innerview.

Inoltre, nel tuo codice ho notato che stai programmando di inviare gli eventi di tocco alle 2 viste dalla classe del contenitore. Ciò causa che InnerView riceve il tocco anche quando SOLO si fa clic su OuterView. Se vuoi quella funzionalità, allora va bene. Se si desidera che InnerView ottenga gli eventi solo quando viene toccato, non si desidera che la classe contenitore invochi esplicitamente su TouchEvent su queste 2 viste. La gerarchia della vista lo farà per te.

Informazioni su come ricevere onFling o onSingleTapConfirmed su BOTH visualizzazioni - (presupponendo che si desideri consentire agli eventi di tocco di passare anche alle visualizzazioni precedenti, si restituisce 'false' da onTouchEvent per InnerView) InnerView ha già passato l'evento alla vista dietro di esso, così non ottiene la fine del gesto per rendersi conto che è appena avvenuta un'avventura e similmente per onSingleTapConfirmed. Se si desidera ottenere ancora tali dati, potrebbe essere necessario inviare programmaticamente gli eventi tattili al termine del gesto, come rilevato da OuterView. Il che significa che se OuterView ha ottenuto un gesto di lancio è stata anche un'avventura per InnerView e quindi programmaticamente fa in modo che quel gesto avvenga anche per InnerView. Questo è piuttosto complicato e il dispacciamento tocchi indietro nella gerarchia non è una cosa usuale.

Speriamo che non ti abbia confuso su questo. Sentiti libero di chiedere se non sono stato chiaro e ci riproverò.

Questo sarà utile: Handling TouchEvents in a ViewGroup

+0

Hi Mistwalker, voglio ricevere onFling(), onSingleTapConfirmed() su entrambi i punti di vista. Stavo solo provando varie opzioni tra cui onInterceptTouchEvent. Sono in grado di farlo funzionare se ho il riferimento della vista inferiore nella parte più in vista ' \t private View outerView = null; \t public void setOuterView (Visualizza outerView) { \t \t this.outerView = outerView; \t} \t \t @Override \t pubblico onTouchEvent booleana (evento MotionEvent) { \t \t gesture.onTouchEvent (evento); \t \t if (outerView! = Null) { \t \t \t outerView.onTouchEvent (evento); \t \t} \t \t return true; \t} ' @mistwalker C'è un modo migliore per raggiungere questo obiettivo? –

+0

Il codice nel mio commento precedente è incasinato. Lo stesso codice è disponibile qui: https://code.google.com/p/ramp-sample/source/browse/android/OverLayView/src/com/example/overlayview/InnerView2.java#55 –

+0

vuoi fare la stessa cosa per le 2 visualizzazioni quando viene rilevata l'apertura/tocco singolo? Quindi sarebbe utile metterli sovrapposti in un FrameLayout e ascoltare i gesti su quel FrameLayout. Altrimenti se si desidera fare cose diverse quando si osservano gli stessi eventi di tocco sulle 2 viste, allora sì, sarà necessario inviare gli eventi touch programmaticamente. Non sono sicuro se ci sono altri modi per raggiungere questo obiettivo. – mistwalker