Подтвердить что ты не робот

ProgressBar в ActionBar, например, приложение GMail с обновлением

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

Спасибо

4b9b3361

Ответ 1

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

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

Я надеюсь, что кто-то найдет это полезным.

Ответ 2

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

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

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

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

Ответ 3

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

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

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

}

Ответ 4

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

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

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

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