ProgressBar в ActionBar, как приложение GMail с обновлением - PullRequest
23 голосов
/ 20 ноября 2011

Я бы хотел сделать то же самое, что и приложение GMail на планшетах Honeycomb.Когда вы нажимаете кнопку «Обновить», значок заменяется панелью ProgressBar.Как я могу это сделать?

Спасибо

Ответы [ 4 ]

25 голосов
/ 23 октября 2012

Хорошо, я попробовал то, что предложил Кайлиан, но у меня это не сработало. Каждый раз, когда я хочу вернуть неопределенный прогресс к исходной кнопке, она становится неактивной, я использовал этот макет для прогресса

(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"/>

и этот, чтобы вернуться к кнопке

(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"/>

мой код был:

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);
    }

После просмотра источника приложения Google IO, особенно этого файла: http://code.google.com/p/iosched/source/browse/android/src/com/google/android/apps/iosched/ui/HomeActivity.java я нашел другой более простой способ.

Теперь мне нужен только первый макет с прогрессом, и метод работы выглядит следующим образом:

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);
}

Определение пункта меню:

<item android:id="@+id/mail_refresh"
      android:title="Refresh"
      android:icon="@drawable/ic_menu_refresh_holo_light"
      android:showAsAction="always"/>

Надеюсь, кто-нибудь найдет это полезным.

25 голосов
/ 20 ноября 2011

Gmail делает это, используя вид действия для своего состояния "выполняется обновление".Вызов обновления выполняется с использованием стандартного действия кнопки / onMenuItemSelected path.

Когда вы входите в состояние обновления, установите для представления действия обновления MenuItem значение ProgressBar.(Создайте его программно, накачайте его из макета, используйте actionLayout в меню xml, как рекомендует CommonsWare, независимо от того, что вы предпочитаете.) Когда вы выходите из своего состояния обновления, установите для представления действия значение null, сохраняя при этом ссылку на него, чтобы вы могли установитьэто снова в следующий раз, когда вы обновите.Вы можете повесить ссылку на MenuItem после того, как наполните меню, и изменения, внесенные в него позже, будут отражены на панели действий.

Этот подход имеет некоторые преимущества по сравнению с использованием полноэкранного вида действия и управлением другими деталями.состояния меняйся сам.Представление действия полностью заменяет сгенерированную кнопку действия для элемента меню, эффективно блокируя возможность пользователю отправлять обычные события onMenuItemSelected для обновления, пока обновление уже выполняется.Еще одна вещь, которую не нужно обрабатывать, и представление действий может оставаться полностью неинтерактивным.

Возможно, вы могли бы сделать что-то умное с ActionProvider в API 14+, чтобы немного больше инкапсулировать весь процесс, но вышеприведенное в конечном итоге выглядит довольно привлекательно.простой.

8 голосов
/ 23 марта 2012

Предполагая, что у вас уже есть настройка пункта меню, вам нужно начать с создания двух новых макетов. Один содержит макет для кнопки обычного обновления, а другой - индикатор выполнения.

Получив их, вызовите следующий фрагмент кода для переключения между двумя макетами. Вам нужно решить, когда именно нужно вызвать его второй раз, чтобы переключить его обратно на значок обновления.

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);

}
1 голос
/ 20 августа 2013

Используйте следующий макет в качестве вида действия для пункта меню панели действий.

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>

Тогда

menuItem.setActionView(R.layout.actionbar_refresh_progress);

Работает через Gingerbread, а все остальное, как шарм. Обратите внимание, что я использовал измерение из панели действий поддержки для совместимости. Вы можете использовать @dimen/action_button_min_width вместо ICS и выше.

Источник: https://code.google.com/p/iosched/source/browse/android/res/layout/actionbar_indeterminate_progress.xml?r=f4fd7504d43b25a75cc23b58d6f844f3553b48c3

...