Skip to main content

Android: pull-to-refresh с двух концов списка

Когда пользователь дойдет до верхнего или нижнего края списка ListView, надо подгрузить следующие записи. Как-то обозначить прогресс выполнения. Если бы подгружать надо было только в конце списка, то можно использовать Endless scrolling ListView. Если только в начале, то компонент ActionBar-PullToRefresh, написанный Chris Banes - впрочем внешний вид компонента красив, поэтому...
Мы хотим что-то в духе ActionBar-PullToRefresh, но с обоих концов списка.

Как отследить событие "оттягивания" края списка? Начиная с 2.3 (api level 9) в android у AbsListView появляется Overscroll: возможность отследить оттягивание края списка. И это прекрасно работает на эмуляторах 2.3 и 4.3, но на телефоне samsung c 2.3 не работает, де самсунг решил не поддерживать эти методы.
Поэтому будем использовать события touch. Возьмём решение Fiddler'a со Stackoverflow.

updatesList.setOnTouchListener(new View.OnTouchListener() {

    private static final float OVERSCROLL_THRESHOLD_IN_PIXELS = 70;

    private float downY;

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        int firstVisibleItem = updatesList.getFirstVisiblePosition();
        int totalItemCount = updatesList.getCount();
        int visibleItemCount = updatesList.getChildCount();
        boolean onTop = firstVisibleItem == 0 && updatesList.getChildAt(0) != null && updatesList.getChildAt(0).getTop() == 0;
        boolean onBottom = firstVisibleItem + visibleItemCount == totalItemCount && updatesList.getChildAt(visibleItemCount - 1).getBottom() == updatesList.getHeight();

        if (onTop || onBottom) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    downY = event.getY();
                    break;
                case MotionEvent.ACTION_MOVE:
                    float deltaY = event.getY() - downY;
                    if (onTop && deltaY > OVERSCROLL_THRESHOLD_IN_PIXELS) {
                        // Top overscroll
                        if (!isOverscrolledNow) {
                            isOverscrolledNow = true;
                            adapter.loadMore(false, UpdatesActivity.this);
                        }
                    }
                    if (onBottom && -deltaY > OVERSCROLL_THRESHOLD_IN_PIXELS) {
                        // Bottom overscroll
                        if (!isOverscrolledNow) {
                            isOverscrolledNow = true;
                            adapter.loadMore(true, UpdatesActivity.this);
                        }
                    }
                    break;
            }
        }
        return false;
    }
});

В начале подгрузки новых записей и в конце адаптер вызовет showPullToRefresh и hidePullToRefresh соответственно:

void showPullToRefresh() {
    getSupportActionBar().hide();
    fakeActionBar.setVisibility(View.VISIBLE);

    loadingBar.setVisibility(View.VISIBLE);
    bar.setIndeterminate(true);
}

void hidePullToRefresh ()
{
    isOverscrolledNow = false;
    getSupportActionBar().show();

    loadingBar.setVisibility(View.INVISIBLE);
    bar.setIndeterminate(false);
}

FakeActionBar, LoadingBar и Bar - это верхний текст, и layout с progressbar'ом. Высоту текста "потяни и увидишь новое" возьмем из темы - это высота ActionBar'a. Но надо куда-то положить ProgressBar. Можно положить его со списком во FrameLayout: когда прогресс видимый, он будет "над" списком, при этом никакого перестроения lyout'а списка при скрытии прогресса не будет. Полный layout (не образец для подражания, впрочем, уж больно много layout'ов накручено) ((странно как-то syntax highlighter показывает xml, TODO: почему??)):


    

        
    

    

        
        

        
        
            
        
    


Ну и наконец, что это за стили у ProgressBar? Это стили из chrisbanes-ActionBar-PullToRefresh. Скопируем оттуда drawable и картинки для анимации progressbar'a.

Comments

  1. Добрый день, очень понравился ваш пример, то что нужно) а можно ли как то посмотреть полный код примера?

    ReplyDelete

Post a Comment

Popular posts from this blog

Блочный, строчный, ...

Сборник советов: 1. Прижать элемент к нижнему краю контейнера: 2 . Две колонки: 3 . Что означает символ ">" в селекторе? Означает, что будут выбраны только прямые потомки. По-умному, direct descendant combinator. Иными словами, если есть: То "div a {color: blue;}" изменит цвет всех ссылок, а "div > a {color: blue;}" - только первой и третьей. 4 . TODO

Hibernate

1. Hibernate Session . Javadoc называет её главным интерфейсом между java-приложением и Hibernate. Иногда её называют единицей работы или логической транзакцией. Основная функция сессии - обеспечить операции создания, чтения, удаления объектов. Объекты могут находиться в одном из 3 состояний (см. 2) Сессия создается с помощью SessionFactory. SessionFactory знает конфигурацию ORM, её внутреннее состояния immutable. При вызове Configuration().configure() загружается файл hibernate.cfg.xml. После того, как конфигурация загружена, можно изменить настройки программно. Данные корректировки возможны только до создания экземпляра фабрики сессий. // Initialize the Hibernate environment Configuration cfg = new Configuration().configure(); // Create the session factory ServiceRegistryBuilder srb = new ServiceRegistryBuilder(); ServiceRegistry sr = srb.applySettings(cfg.getProperties()).buildServiceRegistry(); SessionFactory factory = cfg.buildSessionFactory(sr); // Obtain the new session obj...

Первые шаги в Selenium

Цель расплывчата: понять и сделать хоть что-нибудь =) Selenium Selenium - группа продуктов. Отличное описание в статье Что такое Selenium? Selenium IDE - плагин для Firefox, позволяет записать тест, выполняя действия в браузере. Казалось бы, Selenium WebDriver должен дать больше возможностей: всё таки не из графического интерфейса тесты пишем, а с помощью языка программирования, но интересная мысль в другой статье того же автора  Что такое Selenium WebDriver? : "... WebDriver не имеет прямого отношения к тестированию. Он всего лишь предоставляет автотестам доступ к браузеру. На этом его функции заканчиваются.Структурирование, группировку и запуск тестов, а также генерацию отчётов о тестировании, обеспечивает фреймворк тестирования, такой как JUnit или TestNG для Java, .."  Локаторы Выбрать элемент на странице можно используя локаторы. Локаторы (в Selenium IDE в поле target) используют DOM, XPath или CSS (или просто ищут по id/name). Полезное: XPath: XML Path La...