2014-06-06 12 views
5

sto sviluppando un lanciatore, ora sto lavorando con i widget di app, seguo il tutorial da qui: AppWigetHost tutrial - Leonardo Fischer Tutto va bene fino a quando ho provato ad aggiungere ascoltatore onLongCick sul AppWidgetHostViewAppWidgetHostView non può gestire onClick/onLongClick correttamente

Quando ho aggiunto un widget sull'host (l'orologio analogico di Google predefinito) - e ho provato a fare un lungo clic su di esso, semplicemente non funziona! Dopo il lungo clic apre l'applicazione Orologio (azione predefinita per il clic).

Qualcuno può dirmi come risolvere il problema? Qui è il mio codice completo: http://pastebin.com/61TkuLvx

Aggiunto Ho appena controllato di nuovo:
---- Se ho tempo scatto sopra il limite del widget orologio, l'evento longClick è sparato!
---- Ho aggiunto la mia appwidget personalizzata (che non ha un gestore onclick): quindi l'evento longclick viene sempre attivato correttamente.
Quindi immagino, deve avere qualcosa da fare con il gestore di touchevent/dispatcher.

Aggiunto ho solo cercato di impostare onLongClick su tutti i figli della hostview in questo modo:

private void createAppWidget(Intent data) { 
... 
... 
    setChildrenViewLongClick(hostView, new OnLongClickListener() { 
     @Override 
     public boolean onLongClick(View v) { 
      Toast.makeText(getApplicationContext(), "Long click " + appWidgetId, Toast.LENGTH_LONG).show(); 
      return true; 
     } 
    }); 
} 

protected void setChildrenViewLongClick(View view, OnLongClickListener listener) { 
    view.setOnLongClickListener(listener); 
    String name = view.getClass().getName(); 
    Logger.logInfo("Classname: " + name); 
    if (view instanceof ViewGroup) { 
     ViewGroup vg = (ViewGroup) view; 
     for(int i = 0 ; i < vg.getChildCount() ; i++) { 
      setViewLongClick(vg.getChildAt(i), listener); 
     } 
    } 
} 

Semplicemente non funziona :(

La cosa strana è: ho fatto un altro esperimento su un'altra attività, che ha un LL Linearlayout (ha un gestore onLongClick) contiene 2 pulsanti bt1, bt2 - (ogni pulsante ha il gestore onClick) e applica il metodo setChildrenViewLongClick (LL, onLongClickListener) - quindi fai un lungo clic su bt2 - Woop, funziona, l'azione all'interno di onLongClickListener viene chiamata!
Quindi qual è il problema? AppWidgetHostView o il dispatcher di evento/gestore? O me (i miei codici)

Sono così confuso, per favore aiutatemi!

Tks

risposta

3

dopo alcuni giorni senza alcuna risposta da Così, ho provato a leggere il codice sorgente di Trebuchet-launcher Si scopre molto semplice: si estende l'AppWidgetHostView e l'override del metodo onInterceptTouchEvent() come this source code - I non l'ho ancora provato, ma immagino che funzionerà :).

Spero che questo aiuti qualcuno come me :)

1

ho incontrato lo stesso problema, ho risolto sovrascrivendo il metodo

ViewGroup#onInterceptTouchEvent(MotionEvent ev). 

Vedere "Managing Touch Events in a ViewGroup" per i dettagli.

+1

post importante parte del collegamento. – Rakib

3

La risposta di Hungson175 è stata ottima ma non mi ha portato fino in fondo. Dal momento che sto usando AppWidgetHost per creare AppWidgetHostView, avevo bisogno di estendere sia AppWidgetHost che AppWidgetHostView. Fortunatamente questo è abbastanza semplice da fare e non richiede troppo override dei metodi Android predefiniti.

WidgetHost

public class WidgetHost extends AppWidgetHost { 

    public WidgetHost(Context context, int hostId) { 
     super(context, hostId); 
    } 

    @Override 
    protected AppWidgetHostView onCreateView(Context context, int appWidgetId, AppWidgetProviderInfo appWidget) { 
     // pass back our custom AppWidgetHostView 
     return new WidgetView(context); 
    } 
} 

WidgetView

public class WidgetView extends AppWidgetHostView { 

    private OnLongClickListener longClick; 
    private long down; 

    public WidgetView(Context context) { 
     super(context); 
    } 

    public WidgetView(Context context, int animationIn, int animationOut) { 
     super(context, animationIn, animationOut); 
    } 

    @Override 
    public void setOnLongClickListener(OnLongClickListener l) { 
     this.longClick = l; 
    } 

    @Override 
    public boolean onInterceptTouchEvent(MotionEvent ev) { 
     switch(MotionEventCompat.getActionMasked(ev)) { 
      case MotionEvent.ACTION_DOWN: 
       down = System.currentTimeMillis(); 
       break; 
      case MotionEvent.ACTION_MOVE: 
       boolean upVal = System.currentTimeMillis() - down > 300L; 
       if(upVal) { 
        longClick.onLongClick(WidgetView.this); 
       } 
       break; 
     } 

     return false; 
    } 
} 

Speranza che aiuta qualcuno, perché si tratta di AppWidget di è abbastanza difficile.

+0

Grazie Chris, e se posso, basta aggiungere (restituisce true;) dopo longClick.onLongClick (WidgetView.this); altrimenti aprirà il widget come se fosse un clic insieme al risultato di un clic lungo (in questo caso mostra il brindisi) ... Anche cambiando MotionEvent.ACTION_MOVE su ACTION_UP lo chiamerà una volta invece di chiamarlo più volte. –

Problemi correlati