SwipeRefreshLayout — PullToRefresh из Material Design

Представляю вашему вниманию очень вольный перевод этой статьи.

Одной из отличных идей сформулированных в новом MaterialDesign это SwipeToRefresh. Вы, наверное, уже видели или, даже, использовали его. Этот UI-паттерн используется в популярных программах, таких как Facebook, Google Преccа, Trello, Gmail и многих других.

Вот как он выглядит:

catnames

SwipeToRefresh хорошо подходит для тех RecyclerView и ListView, которые нуждаются в обновлении по запросу пользователя.Представленная вместе с KitKat и улучшенная в Lollilop Android Support-библиотека, включает в себя SwipeToRefresh и называется SwipeRefreshLayout. Все, что мы должны сделать, это подключить библиотеку.  Кстати, проект, который мы  создадим доступен для скачивания на GitHub.

Настраиваем Swipe To Refresh

Мы начнем реализовывать SwipeToRefresh-паттерн в новой Android Studioи новейшей  Android Support Library (ваш SDK-менеджер должен показатьAndroid Support Library версии 21.0).

Во-первых, мы должны добавить эти строки в файл build.gradle нашего приложения.

compile 'com.android.support:support-v4:21.0.+'

Теперь мы должны добавить  ListView и SwipeRefreshLayout в наш layout-файл. ListView отображает контент, который мы хотим обновить, используя SwipetoRefresh-паттерн, а SwipeRefreshLayout обеспечит нам базовую функциональность.

<android.support.v4.widget.SwipeRefreshLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/activity_main_swipe_refresh_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <ListView
            android:id="@+id/activity_main_listview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            >
        </ListView>
</android.support.v4.widget.SwipeRefreshLayout>

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

Подключение адаптера

Теперь, когда мы наш layout-файл готов, давайте настроим простой адаптер данных.В реальной жизни, наше приложение, скорее всего, обращалась к удаленному API или базе данных, но для простоты мы будем имитировать ответ от сервера. Добавим следующие строки в файл res/ strings.xml:

<string-array name="cat_names">
    <item>George</item>
    <item>Zubin</item>
    <item>Carlos</item>
    <item>Frank</item>
    <item>Charles</item>
    <item>Simon</item>
    <item>Fezra</item>
    <item>Henry</item>
    <item>Schuster</item>
</string-array>

и отдадим адаптеру  ответ от нашего «Web-сервера».

 private SwipeRefreshLayout mSwipeRefreshLayout;
    private ListView mListView;
    private ArrayAdapter<String> mAdapter;
    private List<String> mCatNames;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.activity_main_swipe_refresh_layout);
        mListView = (ListView) findViewById(R.id.activity_main_listview);
        mCatNames = Arrays.asList(getResources().getStringArray(R.array.cat_names));
        mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mCatNames);
        mListView.setAdapter(mAdapter);
}
  
 private List<String> getNewCatNames() {
        List<String> newCatNames = new ArrayList<String>();
        for (int i = 0; i < mCatNames.size(); i++) {
            int randomCatNameIndex = new Random().nextInt(mCatNames.size() - 1);
            newCatNames.add(mCatNames.get(randomCatNameIndex));
        }
        return newCatNames;
    }

 

Реализуем обновление данных

Теперь, когда наш адаптер настроен, мы можем потянуть ListView вниз и увидеть индикатор загрузки. Но этот индикатор работает в мы просто должны определили, что происходит с нашим ListView во время загрузки. Мы сделаем это, определив интерфейс OnRefreshListener виджета SwipeRefreshLayout. Мы также должны смоделировать получение новых данных от сервера. Мы создадим метод getNewCatNames(), в котором будем создавать массив и случайным образом переставлять в нем имена кошек.

@Override
  public void onCreate(Bundle savedInstanceState) {
  ...
    listView.setAdapter();
    mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        mAdapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, getNewCatNames());
                        mListView.setAdapter(mAdapter);
                        mSwipeRefreshLayout.setRefreshing(false);
                    }
                }, 2500);
            }
        });
  }
  
 private List<String> getNewCatNames() {
        List<String> newCatNames = new ArrayList<String>();
        for (int i = 0; i < mCatNames.size(); i++) {
            int randomCatNameIndex = new Random().nextInt(mCatNames.size() - 1);
            newCatNames.add(mCatNames.get(randomCatNameIndex));
        }
        return newCatNames;
  }

Обратите внимание на последнюю строку в методе refreshContent(): setRefreshing(false);. Вызывая этот метод мы сообщаем SwipeRefreshLayout’у, что работа завершена и нужно прекратить отображение анимации загрузки.

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

Настройка

Вы также можете настроить внешний вид SwipeRefreshLayout. Чтобы определить свою цветовую схему для индикатора загрузки вызовите метод setColorSchemeResources() у SwipeRefreshLayout. В качестве аргументов передайте идентификаторы цветовых ресурсов.

Для начала определим цвета, которые будут отображаться индикаторе SwipeRefreshLayout’а:

<resources>
    <color name="orange">#FF9900</color>
  <color name="green">#009900</color>
    <color name="blue">#000099</color>
</resources>

Вызовем метод setColorSchemeResources() в onCreate:

mSwipeRefreshLayout.setColorSchemeResources(R.color.orange, R.color.green, R.color.blue);

Откройте приложение и обратите внимание на цветной индикатор загрузки!

catnamescolor

SwipeRefreshLayout будет вращаться через цвета мы, предоставляемых в качестве загрузчика по-прежнему отображается.

Как вы можете видеть из этого простого примера, SwipeToRefresh — это отличный паттерн для отображения загрузки. Для получения дополнительной информации о доступных опциях для SwipeRefreshLayout, почитайте официальную документацию.

Библиотека на GitHub: SwipeRefreshLayout.
Исходники примера: SwipeRefreshLayout.

Комментарии:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *