Pasek postępu w pasku akcji, jak aplikacja GMail z odświeżaniem

Chciałbym zrobić to samo, co aplikacja GMail na tabletach Honeycomb. Po kliknięciu przycisku Odśwież ikonę zastępuje pasek postępu. Jak mogę to zrobić?

Thanks

Author: Ahmad, 2011-11-20

4 answers

Ok, próbowałem tego, co zasugerował Cailean, ale mi nie wyszło. Za każdym razem, gdy chcę przywrócić nieokreślony postęp do oryginalnego przycisku, staje się on nieczytelny, używałem tego układu dla postępu

(actionbar_refresh_progress.xml)

<?xml version="1.0" encoding="utf-8"?>
<ProgressBar xmlns:android="http://schemas.android.com/apk/res/android"
             android:layout_width="32dp"
             android:layout_height="32dp"
             android:layout_gravity="center"/>

I ten do powrotu do przycisku

(actionbar_refresh_button.xml)

<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
           android:src="@drawable/ic_menu_refresh_holo_light"
           android:layout_height="wrap_content"
           android:layout_width="wrap_content"/>

Mój kod to:

private void setRefreshing(boolean refreshing) {
        this.refreshing = refreshing;
        if(refreshMenuItem == null) return;
        View refreshView;
        LayoutInflater inflater = (LayoutInflater)getActionBar().getThemedContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        if(refreshing)
            refreshView = inflater.inflate(R.layout.actionbar_refresh_progress, null);
        else
            refreshView = inflater.inflate(R.layout.actionbar_refresh_button, null);

        refreshMenuItem.setActionView(refreshView);
    }

Po przejrzeniu źródła aplikacji Google IO, zwłaszcza tego pliku: http://code.google.com/p/iosched/source/browse/android/src/com/google/android/apps/iosched/ui/HomeActivity.java{[17]znalazłem inny łatwiejszy sposób.

Teraz potrzebuję tylko pierwszego layoutu z postępem, a metoda pracy wygląda tak:

private void setRefreshing(boolean refreshing) {
    this.refreshing = refreshing;
    if(refreshMenuItem == null) return;

    if(refreshing)
        refreshMenuItem.setActionView(R.layout.actionbar_refresh_progress);
    else
        refreshMenuItem.setActionView(null);
}

Definicja pozycji Menu:

<item android:id="@+id/mail_refresh"
      android:title="Refresh"
      android:icon="@drawable/ic_menu_refresh_holo_light"
      android:showAsAction="always"/>
Mam nadzieję, że komuś się to przyda.
 25
Author: Ivan G.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-23 19:44:39

Gmail robi to za pomocą widoku akcji dla stanu" odświeżanie w toku". Wywołanie odświeżania odbywa się przy użyciu standardowego przycisku akcji/onmenuitemselected path.

Po wprowadzeniu stanu odświeżania Ustaw widok akcji Menu Odśwież na pasek postępu. (Utwórz go programowo, napompuj z układu, użyj actionLayout w menu XML, jak podpowiada CommonsWare, cokolwiek wolisz.) Po wyjściu ze stanu odświeżania Ustaw widok akcji z powrotem na null, zachowując odwołaj się do niego, więc możesz ustawić go ponownie przy następnym odświeżaniu. Po napompowaniu menu możesz zawiesić odniesienie do menu, a zmiany w nim później zostaną odzwierciedlone na pasku akcji.

To podejście ma pewne zalety w stosunku do korzystania z widoku akcji w pełnym wymiarze czasu i zarządzania innymi szczegółami zmiany stanu samodzielnie. Widok akcji całkowicie zastępuje wygenerowany przycisk akcji dla elementu menu, skutecznie blokując użytkownikowi możliwość wysłania zwykłego onmenuitemwybrane zdarzenia do odświeżania, gdy odświeżanie jest już w toku. Jedna rzecz mniej do obsługi i widok akcji może pozostać całkowicie nieinteraktywny.

Prawdopodobnie mógłbyś zrobić coś sprytnego za pomocą ActionProvider w API 14+, aby zamknąć cały proces nieco bardziej, ale powyższe jest dość proste.

 25
Author: adamp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-20 01:28:53

Zakładając, że masz już skonfigurowany element menu, musisz zacząć od utworzenia dwóch nowych układów. Jeden zawierający układ zwykłego przycisku odświeżania, a drugi zawierający pasek postępu.

Gdy już je masz, wywołaj następujący fragment kodu, aby przełączać się między dwoma układami. To od Ciebie zależy, kiedy dokładnie trzeba go wywołać po raz drugi, aby przełączyć go z powrotem na ikonę odświeżania.

private void doRefresh(Boolean refreshing, MenuItem menuItem)
{
    View refreshView;
    LayoutInflater inflater = (LayoutInflater) getActionBar().getThemedContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    if(refreshing)
        refreshView = inflater.inflate(R.layout.actionbar_indeterminate_progress, null);
    else
        refreshView = inflater.inflate(R.layout.refresh_icon, null);

    menuItem.setActionView(refreshView);

}
 8
Author: Cailean,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-23 19:28:17

Użyj następującego układu jako widoku operacji dla elementu menu pasek operacji.

Actionbar_refresh_progress.xml

<FrameLayout
    android:layout_height="wrap_content"
    android:layout_width="@dimen/abc_action_button_min_width"
    android:minWidth="@dimen/abc_action_button_min_width">
    <ProgressBar
        android:layout_width="32dp"
        android:layout_height="32dp"
         android:layout_gravity="center"
         style="?indeterminateProgressStyle" />
</FrameLayout>

Then

menuItem.setActionView(R.layout.actionbar_refresh_progress);
Działa na pierniki, a reszta jak urok. Zauważ, że dla zgodności używałem dimension z paska akcji wsparcia. Możesz użyć @dimen/action_button_min_width zamiast ICS i up.

Źródło: https://code.google.com/p/iosched/source/browse/android/res/layout/actionbar_indeterminate_progress.xml?r=f4fd7504d43b25a75cc23b58d6f844f3553b48c3

 1
Author: Ε Г И І И О,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-20 09:39:42