Когда пользователь дойдет до верхнего или нижнего края списка 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.
В начале подгрузки новых записей и в конце адаптер вызовет showPullToRefresh и hidePullToRefresh соответственно:
FakeActionBar, LoadingBar и Bar - это верхний текст, и layout с progressbar'ом. Высоту текста "потяни и увидишь новое" возьмем из темы - это высота ActionBar'a. Но надо куда-то положить ProgressBar. Можно положить его со списком во FrameLayout: когда прогресс видимый, он будет "над" списком, при этом никакого перестроения lyout'а списка при скрытии прогресса не будет. Полный layout (не образец для подражания, впрочем, уж больно много layout'ов накручено) ((странно как-то syntax highlighter показывает xml, TODO: почему??)):
Ну и наконец, что это за стили у ProgressBar? Это стили из chrisbanes-ActionBar-PullToRefresh. Скопируем оттуда drawable и картинки для анимации progressbar'a.
Мы хотим что-то в духе 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.
Добрый день, очень понравился ваш пример, то что нужно) а можно ли как то посмотреть полный код примера?
ReplyDelete