Освой программирование играючи

Сайт Александра Климова

Шкодим

/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000

SwipeRefreshLayout

В марте 2014 года был представлен новый компонент android.support.v4.widget.SwipeRefreshLayout, который входит в состав библиотеки Support Library v4.


compile 'com.android.support:support-v4:25.0.0'

Компонент позволяет отказаться от сторонних библиотек и собственных велосипедов для реализации шаблона "Pull to Refresh", когда пользователь сдвигает экран, чтобы обновить данные. Подобное поведение можно увидеть в клиентах для Твиттера, чтобы получить новую порцию твитов, не дожидаясь, когда список сообщений обновится самостоятельно.

Создадим новый проект. Начнём с разметки и обернём компоненты новым родительским элементом android.support.v4.widget.SwipeRefreshLayout. На панели инструментов данного компонента нет, поэтому придётся писать код вручную.


<android.support.v4.widget.SwipeRefreshLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/swipe_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
 
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">
 
        <TextView
            android:id="@+id/textViewCat"
            android:text="Hello Kitty"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:gravity="center"/>
    </ScrollView>
 
</android.support.v4.widget.SwipeRefreshLayout>

И небольшой код:


package ru.alexanderklimov.test;

import android.os.Bundle;
import android.os.Handler;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;

import java.util.Random;

public class MainActivity extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener {

    private SwipeRefreshLayout mSwipeRefreshLayout;
    private TextView mCatTextView;

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

        mCatTextView = (TextView) findViewById(R.id.textViewCat);

        mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container);
        mSwipeRefreshLayout.setOnRefreshListener(this);


        mSwipeRefreshLayout.setColorSchemeResources(android.R.color.holo_blue_bright,
                android.R.color.holo_green_light,
                android.R.color.holo_orange_light,
                android.R.color.holo_red_light);

        // Альтернативный способ
        //  mSwipeRefreshLayout.setColorSchemeColors(
        //  Color.RED, Color.GREEN, Color.BLUE, Color.CYAN);

        // Устаревший код
        //  mSwipeRefreshLayout.setColorScheme(android.R.color.holo_blue_bright,
        //          android.R.color.holo_green_light,
        //          android.R.color.holo_orange_light,
        //          android.R.color.holo_red_light);
    }

    @Override
    public void onRefresh() {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                // Отменяем анимацию обновления
                mSwipeRefreshLayout.setRefreshing(false);
                Random random = new Random();
                mCatTextView.setText("Котика пора кормить. Его не кормили уже "
                        + (1 + random.nextInt(10)) + " мин.");
            }
        }, 4000);
    }
}

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

При первом появлении библиотеки использовался метод setColorScheme(), который объявлен устаревшим. Вместо него появились два новых метода setColorSchemeColors() и setColorSchemeResources(). Принцип остался тот же, вам нужно указать четыре цвета по константам Color.XXX или из ресурсов. Старый код закомментировал на память. Вы можете не использовать вызов метода с цветными линиями, тогда будет выводиться только черная линия по умолчанию.

Компонент достаточно интересный с занимательной анимацией. Вначале анимация представляла собой цветные полоски под заголовком программы, как представлено на видео.

Позже анимацию заменили в стиле Material Design, теперь это маленький кружочек, внутри которого крутятся цветные линии (или черная линия, если не использовать метод setColorSchemeResources() со цветами).

Обновляем список

По такому же принципу обновляем данные в списке.


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

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</android.support.v4.widget.SwipeRefreshLayout>

При каждой попытке обновить список будет добавляться текущая дата и время.


import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


public class MainActivity extends AppCompatActivity {

    private SwipeRefreshLayout mSwipeRefreshLayout;
    private ListView mListView;

    private List<String> mList;

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

        mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout);
        mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                String currentDateTime = DateFormat.getDateTimeInstance().format(new Date());
                mList.add(currentDateTime);
                mListView.invalidateViews();
                mSwipeRefreshLayout.setRefreshing(false);
            }
        });

        mListView = (ListView)findViewById(R.id.listView);

        mList = new ArrayList<>();
        ListAdapter mAdapter = new ArrayAdapter<>(
                this, android.R.layout.simple_list_item_1, mList);
        mListView.setAdapter(mAdapter);
    }
}

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

Дополнительное чтение

vaigunth/card-printer: Pull down to refresh - card printer

Cleveroad/FireworkyPullToRefresh: Let's try to refresh your data with our library! - интересный эффект обновления.

Реклама