2012-11-24 9 views
10
public boolean onOptionsItemSelected(MenuItem item) { 
    switch (item.getItemId()) { 

    case android.R.id.home: 
     return true; 

    case R.id.searchIcon: 
     return true; 

    case R.id.startRefresh: 
     refreshItem = item; 
     refresh(); 
     return true; 
    case R.id.stopRefresh: 

     if (refreshItem != null && refreshItem.getActionView() != null) { 
      refreshItem.getActionView().clearAnimation(); 
      refreshItem.setActionView(null); 
     } 
     return true; 
    default: 
     return super.onOptionsItemSelected(item); 
    } 
} 


public void refresh() { 
    if (FeedActivity.this != null) { 
     /* 
     * Attach a rotating ImageView to the refresh item as an ActionView 
     */ 
     LayoutInflater inflater = (LayoutInflater) FeedActivity.this 
       .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     ImageView iv = (ImageView) inflater.inflate(
       R.layout.refresh_action_view, null); 
     Animation rotation = AnimationUtils.loadAnimation(
       FeedActivity.this, R.anim.clockwise_refresh); 
     rotation.setRepeatCount(Animation.INFINITE); 
     iv.startAnimation(rotation); 
     refreshItem.setActionView(iv); 
    } 
} 

prima di fare clic:Aggiorna voce di menu di animazione in ActionBarSherlock

enter image description here

Dopo Cliccando:

enter image description here

Qui l'icona è in corso di animazione (a rotazione).

Problema:

perché è spostando a sinistra?

una volta che si sposta a sinistra, l'icona diventa non cliccabile e stranamente il dispositivo pulsante Indietro anche non funziona

EDIT:

In commenti qui sotto questa risposta:

Animated Icon for ActionItem

Jake Warton dice che se si utilizza un'icona di dimensioni quadrate e corrette per la voce di menu, non si otterrà questo comportamento strano, a qualcuno che ha lo stesso pr oblema.

Ma sto usando un'immagine 32x32 su un dispositivo che utilizza i drawable mdpi. Il che come detto ci deve lavorare :(

Thank You

EDIT:

refresh_action_view.xml

<?xml version="1.0" encoding="utf-8"?> 
<ImageView xmlns:android="http://schemas.android.com/apk/res/android" 
    style="@style/Widget.Sherlock.ActionButton" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:src="@drawable/ic_refresh" /> 

stile personalizzato che uso nel mio app

<style name="My_solid_ActionBar" parent="@style/Widget.Sherlock.Light.ActionBar.Solid.Inverse"> 
    <item name="background">@drawable/ab_solid_My</item> 
    <item name="backgroundStacked">@drawable/ab_stacked_solid_My</item> 
    <item name="backgroundSplit">@drawable/ab_bottom_solid_My</item> 
    <item name="progressBarStyle">@style/My_ProgressBar</item> 
    <item name="android:background">@drawable/ab_solid_My</item> 
    <item name="android:backgroundStacked">@drawable/ab_stacked_solid_My</item> 
    <item name="android:backgroundSplit">@drawable/ab_bottom_solid_My</item> 
    <item name="android:progressBarStyle">@style/My_ProgressBar</item> 
</style> 
+0

FWIW, ecco un progetto che dimostra l'effetto desiderato, nel caso in cui fornisca qualche idea: https://github.com/commonsguy/cw-omnibus/tree/master/Progress/ActionBar – CommonsWare

+0

Sì, ho usato il tuo codice e anche ora la barra di avanzamento (impostata come ActionView) si sposta a sinistra. E nessuna delle altre voci di menu funziona. –

+0

Dovresti pubblicare un progetto di esempio completo che mostri il tuo problema. Se nel mio esempio collegato sopra, faccio 'about' be' always' e il primo elemento della barra delle azioni, il mio 'refresh' funziona ancora, senza mostrare il comportamento che descrivi. – CommonsWare

risposta

8

Il problema è che non si sta gestendo tutto il gonfiaggio dei menu in onCreateOptionsMenu(). La logica di base per un'animazione di aggiornamento ActionBar che ho visto utilizzata nelle app con open source, ad esempio Andlytics (e anche utilizzata nei progetti), consiste nell'implementare un flag boolean in onCreateOptionsMenu() per decidere se mostrare l'animazione di aggiornamento.

È possibile implementare in questo modo: quando il metodo refresh() viene chiamato, si imposta il flag booleanisRefreshing alla vera e chiede inValidateOptionsMenu() che 'dietro le quinte' chiama onCreateOptionsMenu() per avviare l'animazione:

gonfiare il menu onCreateOptionsMenu(...):

@Override 
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
    menu.clear(); 
    super.onCreateOptionsMenu(menu, inflater); 
    //inflate a menu which shows the non-animated refresh icon 
    inflater.inflate(R.menu.my_ab_menu, menu); 

    if (isRefreshing) { 
     //if we're refreshing, show the animation 
     MenuItem item = menu.findItem(R.id.refreshMenuItem); 
     item.setActionView(R.layout.action_bar_indeterminate_progress); 
     ImageView iv = (ImageView) item.getActionView().findViewById(R.id.loadingImageView); 
     ((AnimationDrawable) iv.getDrawable()).start(); 
    } 
} 

animazione di avvio in questo modo:

public void refresh(){ 
     isRefreshing = true; 
     inValidateOptionsMenu(); 
    } 

Se si desidera che l'utente per avviare l'animazione quando tocca l'icona di aggiornamento, fare come questo in onOptionsItemSelected():

case R.id.refreshMenuItem: 
    isRefreshing = true; 
    item.setActionView(R.layout.action_bar_indeterminate_progress); 
    ImageView iv = (ImageView) item.getActionView().findViewById(R.id.loadingImageView); 
    ((AnimationDrawable) iv.getDrawable()).start(); 
    //... 

Per interrompere la chiamata di animazione:

isRefreshing = false; 
invalidateOptionsMenu(); 

Questo codice è da un Fragment quindi potresti dover modificare se per un Activity, ma penso che comunichi l'idea di base.

+0

Ma in tutti gli esempi che ho visto, lì non è niente come ** invalidateOptionsMenu(); **. Come nell'esempio che ho nella domanda e 1 che CommonsWare ha pubblicato nei commenti. Proveremo questo però. –

+0

Ci sono diversi modi per ottenere lo stesso effetto. Ho trovato questo approccio semplice da capire e correggere. Dai un'occhiata all'esempio di app di Andlytics. Puoi scaricarlo dal mercato e vedere come funziona come un esempio reale. –

+0

Ho modificato la risposta per mostrare come gestire l'aggiornamento avviato dall'utente anziché avviare solo a livello di codice l'animazione di aggiornamento. Dovresti aggiungere dei controlli se sta già animando quando l'utente tocca ecc ... –

0

Ho provato lo stesso identico codice che usi e funziona perfettamente per me. Le uniche cose che potrebbero essere differenti sono due cose:

1) il layout refresh_action_view (qui è mio per il confronto):

<?xml version="1.0" encoding="utf-8"?> 
<ImageView xmlns:android="http://schemas.android.com/apk/res/android" 
    style="?attr/actionButtonStyle" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:src="@drawable/ic_menu_refresh" /> 

2) Le opzioni di visualizzazione della vostra barra di azione (qui è il mio styles.xml per confronto).

<resources> 

<style name="AppTheme" parent="Theme.Sherlock.Light.DarkActionBar"> 
    <item name="android:actionBarStyle">@style/Widget.ActionBar</item> 
    <item name="actionBarStyle">@style/Widget.ActionBar</item> 
</style> 

<style name="Widget.ActionBar" parent="Widget.Sherlock.Light.ActionBar.Solid.Inverse"> 
    <item name="android:displayOptions">showHome|useLogo|showCustom</item> 
    <item name="displayOptions">showHome|useLogo|showCustom</item> 
</style> 

</resources> 

Puoi condividere anche il tuo?

+0

sì fatto.Per favore controlla la parte Modifica –

Problemi correlati