2012-10-19 12 views
17

Come rilevare l'evento tocco se l'utente tocca la vista A e trascina verso il basso sulla vista B. Voglio rilevare l'evento tocco nella Vista B.Rileva evento tocco su una vista trascinato da un'altra vista

ho aggiunto tocco ascoltatore in vista B, ma non riceve gli eventi se l'utente inizialmente toccato a e trascinato sopra la B.

enter image description here

+0

[VEDERE QUESTO ANCHE] (http://stackoverflow.com/questions/13309111/programatically-execute-another-touch-event-when-to-touch-event-occures-in-andr) –

risposta

53

Puoi usa il codice qui sotto per ottenere la tua richiesta:

Metodo per testare vista limiti (utilizzato nel codice beloow)

Rect outRect = new Rect(); 
    int[] location = new int[2]; 

    private boolean isViewInBounds(View view, int x, int y){ 
     view.getDrawingRect(outRect); 
     view.getLocationOnScreen(location); 
     outRect.offset(location[0], location[1]); 
     return outRect.contains(x, y); 
    } 

Test con due TextView

final TextView viewA = (TextView) findViewById(R.id.textView); 
    final TextView viewB = (TextView) findViewById(R.id.textView2); 

Setup viewA

Il vuoto OnClickListener è tenuto a mantieni OnTouchListener attivo fino ACTION_UP

viewA.setOnClickListener(new OnClickListener() { 
     @Override 
     public void onClick(View v) {} 
    }); 

    viewA.setOnTouchListener(new OnTouchListener() { 
     @Override 
     public boolean onTouch(View v, MotionEvent event) { 
      int x = (int)event.getRawX(); 
      int y = (int)event.getRawY(); 
      if(event.getAction() == MotionEvent.ACTION_UP){ 
       if(isViewInBounds(viewB, x, y)) 
        viewB.dispatchTouchEvent(event); 
       else if(isViewInBounds(viewA, x, y)){ 
        Log.d(TAG, "onTouch ViewA"); 
        //Here goes code to execute on onTouch ViewA 
       } 
      } 
      // Further touch is not handled 
      return false; 
     } 
    }); 

Setup viewB

Questa operazione è necessaria solo se si desidera anche di premere sul viewB e trascinare per viewA

viewB.setOnClickListener(new OnClickListener() { 
     @Override 
     public void onClick(View v) {} 
    }); 

    viewB.setOnTouchListener(new OnTouchListener() { 
     @Override 
     public boolean onTouch(View v, MotionEvent event) { 
      int x = (int)event.getRawX(); 
      int y = (int)event.getRawY(); 
      if(event.getAction() == MotionEvent.ACTION_UP){ 
       if(isViewInBounds(viewA, x, y)) 
        viewA.dispatchTouchEvent(event); 
       else if(isViewInBounds(viewB, x, y)){ 
        Log.d(TAG, "onTouch ViewB"); 
        //Here goes code to execute on onTouch ViewB 
       } 
      } 
      // Further touch is not handled 
      return false; 
     } 
    }); 

saluti.

+1

come apparirebbe il codice in caso di più di 2 viste? –

0

Provare a utilizzare il drag and drop quadro.

+4

Questo è solo disponibile per 3.0 o successive – Magakahn

1

Sono sicuro che è necessario eseguire l'override del metodo ViewGroup.dispatchTouchEvent(MotionEvent ev) nel ViewGroup che contiene le viste A e B. L'implementazione originale definisce la vista di destinazione quando il contenitore riceve MotionEvent.getAction() == MotionEvent.ACTION_DOWN e quindi invia tutti i seguenti eventi di tocco alla vista di destinazione finché non riceve MotionEvent.getAction() == MotionEvent.ACTION_UP o MotionEvent.ACTION_CANCEL.

Nel tuo caso la vista di destinazione è A o il contenitore stesso (si espande sull'implementazione del metodo del contenitore onInterceptTouchEvent(MotionEvent ev)). Pertanto, è necessario ignorare tale comportamento e inviare gli eventi di tocco non solo alla vista di destinazione, ma anche a tutte le viste, che si trovano sotto l'area toccata (ad esempio per visualizzare B).

Se sei interessato puoi condividere il codice di esempio e cercherò di aiutarti ulteriormente.

+0

[HO ANCHE UN PROBLEMA STESSO A QUESTO] (http://stackoverflow.com/questions/13309111/programatically-execute-another-touch-event-when-to-touch-event-occures-in-andr). puoi dare qualche codice demo per aiuto? –

0

Quando si è sopra la vista B, chiamare manualmente è onTouch.

if (viewBRect.contains(x, y)) { 
    viewBsonTouch(view, motionEvent); 
} 
1

Se si restituisce true dall'onTouchEvent della vista A, l'evento non viene propagato. In questo caso particolare, quando A è inferiore a B, restituisce false da onTouch of view A.

Sarebbe inoltre di aiuto se è possibile inserire del codice.

1

In ViewUn, Override onTouchEvent come segue:

@Override 
public boolean onTouchEvent(MotionEvent event) 
{ 

    float x = event.getRawX(); 
    float y = event.getRawY(); 
    if ((B.getLeft() <= x <= B.getRight()) && 
     (B.getTop() <= y <= B.getBottom()) 
     ) 
    { 
     Log.i("A", "Motion Event is currently above B"); 
     B.dispatchTouchEvent(event); 
    } 

    return true; 
} 

In ViewB, sovrascrivere lo stesso metodo, avendo cura di return false:

@Override 
public boolean onTouchEvent(MotionEvent event) 
{ 
    //TODO handle touch event 
    return false;//this will allow A to continue using the event 
} 
+0

Lasciamo @ dcanh121 provarlo prima. Oppure potresti offrire un commento costruttivo, ad esempio perché ritieni che non funzioni e in che modo credi che dovrebbe essere corretto. – Phil

Problemi correlati