2012-11-21 11 views
5

Ho layout del frame:Passo evento click tramite la vista android

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:layout_margin="10dp" > 

<LinearLayout 
    android:id="@+id/widgetView" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:layout_gravity="center" 
    android:layout_margin="10dp" 
    android:gravity="center" > 
</LinearLayout> 

<LinearLayout 
    android:id="@+id/widgetOverlayFrame" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:clickable="false" > 
</LinearLayout> 

primo formato contiene la layout grafico, e secondo è trasparente e riceve onLongClick per trascinare opere method.That, il problema è quando voglio interagire con il widget, fare clic su qualcosa, fare clic su evento è preso da overlayFrame. Come posso passare l'evento click tramite overlayFrame a widgetView?

EDIT:

ora sto cercando di collegare GestureLister a overlayFrame LinearLayout, per vedere in qualche modo differenza tra MotionEvent che rappresentano solo clic e clic lungo. Il problema che sto affrontando è che OnLongPress nel listener di gesti è sempre chiamato qualunque cosa io faccia, clic singolo o clic lungo.

Esiste una spiegazione per questo comportamento? Tnx!

risposta

0

Invece di utilizzare GestureListener è possibile ignorare l'onTouchListener in questo modo.

Questo chiamerà longpress quando il timer si esaurisce e se un up è disponibile in tra essa annulla la longpress

CountDownTimer c; 
    long time=5000; 
    @Override 
    public boolean onTouchEvent(MotionEvent ev) { 
     switch (ev.getAction()) { 
      case MotionEvent.ACTION_DOWN: 
       c= new CountDownTimer(5000, 1000) { 
          public void onTick(long millisUntilFinished) { 
            time=millisUntilFinished; 
          } 

          public void onFinish() { 
           Log.i("","LONG PRESS"); 
          }}.start(); 

      break; 
      case MotionEvent.ACTION_UP: 
       if (time>0) { 
        Log.i("example","short click"); 
        c.cancel(); 
       } 
      break; 
     } 

     return true; 
    } 
+0

Ok, che funziona per rilevamento perfettamente ... come faccio ora a fare clic per passare al livello sottostante? – Veljko

+0

Ho lavorato su come ... tnx per idea! – Veljko

0

Potrebbe essere sufficiente impostare l'attributo overlay android:focusable="false" o android:focusableInTouchMode="false".

È anche possibile creare il proprio widget di sovrapposizione e sovrascrivere il suo metodo onInterceptTouchEvent per restituire false sempre.

public class NotTouchableLinearLayout extends LinearLayout { 

    // Override constructors 
    // ... 

    @Override 
    public boolean onInterceptTouchEvent(MotionEvent ev) { 
     return false; 
    } 
} 
+0

Ho provato sia, niente ha funzionato finora. Qualche altra idea? – Veljko

+0

Provare a ignorare onTouch anziché onInterceptTouchEvent. –

+0

hehe, l'ho fatto, ma ora suLongClick su overlayLayout non viene chiamato. E non posso trascinare gli oggetti. – Veljko

0

Invece di impostare un GestureListener sul layout in alto, è necessario creare la propria classe che si estende LinearLayout e di ignorare è onTouchEvent metodo. Ci si può implementare la logica del click lungo \ rapida clicca ecc

gli eventi click viene prima inviato al layout widget di, e solo se non li gestisce (Quindi è onTouchEvent rendimenti false), si portali sul layout superiore.

edit:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:layout_margin="10dp" > 

<LinearLayout 
android:id="@+id/widgetView" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:layout_gravity="center" 
android:layout_margin="10dp" 
android:gravity="center" > 
</LinearLayout> 

<com.example.touchtesting.MyLinearLayout 
android:id="@+id/widgetOverlayFrame" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:clickable="false" > 
</com.example.touchtesting.MyLinearLayout> 

</FrameLayout> 

cambiamento del com.example.touchtesting al nome del pacchetto. e questa è la classe:

 public class MyLinearLayout extends LinearLayout{ 

     public MyLinearLayout(Context context, AttributeSet attrs) { 
      super(context, attrs); 
     } 

     private long startClick = 0; 

     @Override 
     public boolean onTouchEvent(MotionEvent ev) { 
      switch (ev.getAction()) { 
       case MotionEvent.ACTION_DOWN: 
        startClick = ev.getEventTime(); 
        break; 
       case MotionEvent.ACTION_CANCEL: 
       case MotionEvent.ACTION_UP: 
        if (ev.getEventTime() - startClick < 500) { 
         Log.i("example","short click"); 
        } 
        else { 
         Log.i("example","long click"); 
        } 
        break; 
      } 

      return true; 
     } 

    } 
+0

potresti fornire del codice? – Veljko

+0

ha modificato la risposta – Rotem

+0

lo proverò ora;) tnx ... rende senso ... spero che funzioni ... ho perso un giorno con questo. – Veljko

0

Per ottenere i lunghi scatti di passare attraverso il widgetView LinearLayout aggiungere android:longClickable="true". (Per click ordinarie aggiungere android:clickable="true")

Così widgetView diventa:

<LinearLayout 
    android:id="@+id/widgetView" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:layout_gravity="center" 
    android:layout_margin="10dp" 
    android:gravity="center" 
    android:longClickable="true"> 
</LinearLayout>