Одним из решений является реализация OnScrollListenerи внесение изменений (например, добавление элементов и т. Д.) В ListAdapterудобное состояние onScrollметода.
Ниже ListActivityприведен список целых чисел, начиная с 40, добавление элементов при прокрутке пользователем до конца списка.
Очевидно, что вы должны использовать отдельные потоки для длительных действий (например, загрузки веб-данных) и, возможно, захотите указать прогресс в последнем элементе списка (как это делают приложения market или gmail).
да, не приведет ли это к увеличению размера адаптера, если вы перестанете прокручивать середину экрана? он должен загружать только следующие 10, когда фактически достигнет дна списка.
Матиас
9
Я заметил много примеров, подобных этому, с помощью BaseAdapter. Хотел бы упомянуть, что если вы используете базу данных, попробуйте использовать SimpleCursorAdapter. Когда вам нужно добавить в список, обновить базу данных, получить новый курсор и использовать SimpleCursorAdapter # changeCursor вместе с notifyDataSetChanged. Подклассы не требуются, и он работает лучше, чем BaseAdapter (опять же, только если вы используете базу данных).
Брек
1
После вызова notifyDataSetChanged () он станет первым в списке, как я могу предотвратить это?
ничья
2
Примечание. Я использовал этот подход, но мне нужно было добавить проверку, когда visibleCount равен 0. Для каждого списка я получаю один обратный вызов onScroll, где firstVisible, visibleCount и totalCount равны 0, что технически соответствует условию, но не когда я хочу загрузить больше.
Эрик Милл
5
Другая проблема с этим кодом заключается в том, что условие firstVisible + visibleCount >= totalCountвыполняется несколько раз при нескольких вызовах слушателя. Если функция load-more является веб-запросом (скорее всего, так и будет), добавьте еще одну проверку, выполняется ли запрос или нет. С другой стороны, проверьте, не равен ли totalCount предыдущему общему количеству, потому что нам не нужно несколько запросов для одного и того же количества элементов в списке.
Субин Себастьян
94
Просто хотел предложить решение, которое я использовал для своего приложения.
Он также основан на OnScrollListenerинтерфейсе, но я обнаружил, что он имеет гораздо лучшую производительность прокрутки на младших устройствах, так как во время операций прокрутки не выполняется никаких расчетов видимого / общего количества.
@Overridepublicvoid onScroll(AbsListView view,int firstVisibleItem,int visibleItemCount,int totalItemCount){//leave this empty}@Overridepublicvoid onScrollStateChanged(AbsListView listView,int scrollState){if(scrollState == SCROLL_STATE_IDLE){if(listView.getLastVisiblePosition()>= listView.getCount()-1- threshold){
currentPage++;//load more list items:
loadElements(currentPage);}}}
где currentPage- страница вашего источника данных, которая должна быть добавлена в ваш список, и thresholdколичество элементов списка (отсчитываемых с конца), которые, если они видны, должны инициировать процесс загрузки. Если вы установите thresholdна 0, например, пользователь должен прокрутить до самого конца списка, чтобы загрузить больше деталей.
(необязательно) Как видите, «проверка загрузки» вызывается только тогда, когда пользователь прекращает прокрутку. Чтобы улучшить удобство использования, вы можете надуть и добавить индикатор загрузки в конец списка через listView.addFooterView(yourFooterView). Один пример для такого представления нижнего колонтитула:
Я пробовал это, но это не работает для ListFragment. Как это можно использовать в ListFragment.
Зеешан
Ну, я использую его ListFragmentтакже без проблем - просто следуйте каждому из шагов, описанных выше, и все будет в порядке;) Или вы могли бы предоставить какие-либо сообщения об ошибках?
saschoar
То, что вы, возможно, пропустили, объясняется в этом SO-ответе: stackoverflow.com/a/6357957/1478093 -getListView().setOnScrollListener(this)
TBieniek
7
примечание: добавление и удаление нижнего колонтитула при просмотре списка проблематично (нижний колонтитул не отображается, если setAdapter вызывается перед добавлением нижнего колонтитула), в итоге я изменил видимость представления нижнего колонтитула напрямую, не удаляя его.
dvd
Что должно быть добавлено в loadElements (currentPage) ??? Я имею в виду, я называю мой AsyncTask или поток?
android_developer
20
Вы можете определить конец списка с помощью onScrollListener , рабочий код представлен ниже:
Другой способ сделать это (внутри адаптера) заключается в следующем:
publicView getView(int pos,View v,ViewGroup p){if(pos==getCount()-1){
addMoreData();//should be asynctask or thread}return view;}
Помните, что этот метод будет вызываться много раз, поэтому вам нужно добавить еще одно условие, чтобы заблокировать несколько вызовов addMoreData().
Когда вы добавляете все элементы в список, пожалуйста, вызовите notifyDataSetChanged () внутри вашего адаптера, чтобы обновить представление (его следует запускать в потоке пользовательского интерфейса - runOnUiThread )
Это плохая практика - делать что-то иное, чем возвращать представление getView. Например, вам не гарантировано, что posпросматривает пользователь. Это может быть просто измерение ListView.
Томас Ахл
Я хочу загрузить больше элементов после того, как 10 элементов прокручиваются. но я замечаю, что загрузка начинается до того, как 10-й элемент становится видимым, значит на 9-м элементе. Так как это остановить?
Может быть, немного поздно, но следующее решение оказалось очень полезным в моем случае. Таким образом, все, что вам нужно сделать, это добавить в свой ListView Footerи создать для него addOnLayoutChangeListener.
ListView listView1 =(ListView) v.findViewById(R.id.dialogsList);// Your listViewView loadMoreView = getActivity().getLayoutInflater().inflate(R.layout.list_load_more,null);// Getting your layout of FooterView, which will always be at the bottom of your listview. E.g. you may place on it the ProgressBar or leave it empty-layout.
listView1.addFooterView(loadMoreView);// Adding your View to your listview ...
loadMoreView.addOnLayoutChangeListener(newView.OnLayoutChangeListener(){@Overridepublicvoid onLayoutChange(View v,int left,int top,int right,int bottom,int oldLeft,int oldTop,int oldRight,int oldBottom){Log.d("Hey!","Your list has reached bottom");}});
Это событие срабатывает один раз, когда нижний колонтитул становится видимым и работает как шарм.
Ключ этой проблемы - обнаружить событие load-more, запустить асинхронный запрос данных и затем обновить список. Также необходим адаптер с индикатором загрузки и другими декораторами. На самом деле, проблема очень сложна в некоторых угловых случаях. Просто OnScrollListenerреализации недостаточно, потому что иногда элементы не заполняют экран.
Я написал персональный пакет, который поддерживает бесконечный список RecyclerView, а также предоставляет реализацию асинхронного загрузчика, AutoPagerFragmentкоторая позволяет очень легко получать данные из многостраничного источника. Он может загрузить любую страницу в RecyclerViewпользовательское событие, а не только следующую страницу.
Я работал над другим решением, очень похожим на это, но я использую footerViewзначок footerView, чтобы дать возможность пользователю загружать больше элементов, щелкнув по кнопке « Я», использую «меню», которое показано над ListViewи в нижней части окна. В родительском представлении это «меню» скрывает нижнюю часть ListView, поэтому при listViewпрокрутке меню исчезает, а когда состояние прокрутки бездействует, меню появляется снова, но когда пользователь прокручивает до конца listView, я «прошу» знать footerView, отображается ли в этом случае, меню не появляется, и пользователь может видеть, footerViewчтобы загрузить больше контента. Вот код:
Я знаю, что это старый вопрос, и мир Android в основном перешел на RecyclerViews, но для всех, кому это интересно, эта библиотека может оказаться очень интересной.
Он использует BaseAdapter, используемый с ListView, чтобы определить, когда список был прокручен до последнего элемента или когда он прокручивается от последнего элемента.
Он поставляется с примером проекта (всего 100 строк кода Activity), который можно использовать, чтобы быстро понять, как он работает.
loadMoreЭлемент используется тот или иной элемент интерфейса , который может быть нажат , чтобы извлечь больше данных из URL. При размещении, как описано в коде, адаптер точно знает, когда показывать эту кнопку и когда отключать ее. Просто создайте кнопку в своем XML-файле и поместите ее, как показано в коде адаптера выше.
Ответы:
Одним из решений является реализация
OnScrollListener
и внесение изменений (например, добавление элементов и т. Д.) ВListAdapter
удобное состояниеonScroll
метода.Ниже
ListActivity
приведен список целых чисел, начиная с 40, добавление элементов при прокрутке пользователем до конца списка.Очевидно, что вы должны использовать отдельные потоки для длительных действий (например, загрузки веб-данных) и, возможно, захотите указать прогресс в последнем элементе списка (как это делают приложения market или gmail).
источник
firstVisible + visibleCount >= totalCount
выполняется несколько раз при нескольких вызовах слушателя. Если функция load-more является веб-запросом (скорее всего, так и будет), добавьте еще одну проверку, выполняется ли запрос или нет. С другой стороны, проверьте, не равен ли totalCount предыдущему общему количеству, потому что нам не нужно несколько запросов для одного и того же количества элементов в списке.Просто хотел предложить решение, которое я использовал для своего приложения.
Он также основан на
OnScrollListener
интерфейсе, но я обнаружил, что он имеет гораздо лучшую производительность прокрутки на младших устройствах, так как во время операций прокрутки не выполняется никаких расчетов видимого / общего количества.ListFragment
илиListActivity
реализоватьOnScrollListener
Добавьте следующие методы к этому классу:
где
currentPage
- страница вашего источника данных, которая должна быть добавлена в ваш список, иthreshold
количество элементов списка (отсчитываемых с конца), которые, если они видны, должны инициировать процесс загрузки. Если вы установитеthreshold
на0
, например, пользователь должен прокрутить до самого конца списка, чтобы загрузить больше деталей.(необязательно) Как видите, «проверка загрузки» вызывается только тогда, когда пользователь прекращает прокрутку. Чтобы улучшить удобство использования, вы можете надуть и добавить индикатор загрузки в конец списка через
listView.addFooterView(yourFooterView)
. Один пример для такого представления нижнего колонтитула:(необязательно) Наконец, удалите этот индикатор загрузки, позвонив,
listView.removeFooterView(yourFooterView)
если больше нет элементов или страниц.источник
ListFragment
также без проблем - просто следуйте каждому из шагов, описанных выше, и все будет в порядке;) Или вы могли бы предоставить какие-либо сообщения об ошибках?getListView().setOnScrollListener(this)
Вы можете определить конец списка с помощью onScrollListener , рабочий код представлен ниже:
Другой способ сделать это (внутри адаптера) заключается в следующем:
Помните, что этот метод будет вызываться много раз, поэтому вам нужно добавить еще одно условие, чтобы заблокировать несколько вызовов
addMoreData()
.Когда вы добавляете все элементы в список, пожалуйста, вызовите notifyDataSetChanged () внутри вашего адаптера, чтобы обновить представление (его следует запускать в потоке пользовательского интерфейса - runOnUiThread )
источник
getView
. Например, вам не гарантировано, чтоpos
просматривает пользователь. Это может быть просто измерение ListView.В
Ognyan Bankov GitHub
я нашел простое и работающее решение!Это делает использование
Volley HTTP library
сетей Android-приложений проще, а главное, быстрее. Залп доступен через открытый репозиторий AOSP.Данный код демонстрирует:
Для будущей консистенции я раздвоил репо Банкова .
источник
Вот решение, которое также упрощает отображение представления загрузки в конце ListView во время его загрузки.
Вы можете увидеть классы здесь:
https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/helper/ListViewWithLoadingIndicatorHelper.java - помощник, позволяющий использовать функции без расширения из SimpleListViewWithLoadingIndicator.
https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/listener/EndlessScrollListener.java - прослушиватель, который начинает загрузку данных, когда пользователь собирается достичь дна ListView.
https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/view/SimpleListViewWithLoadingIndicator.java - The EndlessListView. Вы можете использовать этот класс напрямую или расширять его.
источник
Может быть, немного поздно, но следующее решение оказалось очень полезным в моем случае. Таким образом, все, что вам нужно сделать, это добавить в свой ListView
Footer
и создать для негоaddOnLayoutChangeListener
.http://developer.android.com/reference/android/widget/ListView.html#addFooterView(android.view.View)
Например:
Это событие срабатывает один раз, когда нижний колонтитул становится видимым и работает как шарм.
источник
Ключ этой проблемы - обнаружить событие load-more, запустить асинхронный запрос данных и затем обновить список. Также необходим адаптер с индикатором загрузки и другими декораторами. На самом деле, проблема очень сложна в некоторых угловых случаях. Просто
OnScrollListener
реализации недостаточно, потому что иногда элементы не заполняют экран.Я написал персональный пакет, который поддерживает бесконечный список
RecyclerView
, а также предоставляет реализацию асинхронного загрузчика,AutoPagerFragment
которая позволяет очень легко получать данные из многостраничного источника. Он может загрузить любую страницу вRecyclerView
пользовательское событие, а не только следующую страницу.Вот адрес: https://github.com/SphiaTower/AutoPagerRecyclerManager
источник
Лучшее решение, которое я когда-либо видел, - это библиотека FastAdapter для представлений переработчика. Это имеет
EndlessRecyclerOnScrollListener
.Вот пример использования: EndlessScrollListActivity
Как только я использовал его для бесконечной прокрутки списка, я понял, что настройка очень надежна. Я определенно рекомендую это.
источник
Я работал над другим решением, очень похожим на это, но я использую
footerView
значокfooterView
, чтобы дать возможность пользователю загружать больше элементов, щелкнув по кнопке « Я», использую «меню», которое показано надListView
и в нижней части окна. В родительском представлении это «меню» скрывает нижнюю частьListView
, поэтому приlistView
прокрутке меню исчезает, а когда состояние прокрутки бездействует, меню появляется снова, но когда пользователь прокручивает до концаlistView
, я «прошу» знатьfooterView
, отображается ли в этом случае, меню не появляется, и пользователь может видеть,footerView
чтобы загрузить больше контента. Вот код:С уважением.
источник
Я знаю, что это старый вопрос, и мир Android в основном перешел на RecyclerViews, но для всех, кому это интересно, эта библиотека может оказаться очень интересной.
Он использует BaseAdapter, используемый с ListView, чтобы определить, когда список был прокручен до последнего элемента или когда он прокручивается от последнего элемента.
Он поставляется с примером проекта (всего 100 строк кода Activity), который можно использовать, чтобы быстро понять, как он работает.
Простое использование:
Адаптер для хранения объектов Boy будет выглядеть так:
Обратите внимание, как метод getView BoysAdapter возвращает вызов метода суперкласса EndlessAdapter
getView
. Это на 100% важно.Теперь, чтобы создать адаптер, выполните:
loadMore
Элемент используется тот или иной элемент интерфейса , который может быть нажат , чтобы извлечь больше данных из URL. При размещении, как описано в коде, адаптер точно знает, когда показывать эту кнопку и когда отключать ее. Просто создайте кнопку в своем XML-файле и поместите ее, как показано в коде адаптера выше.Наслаждаться.
источник