Android: Implementing progressbar and "loading..." for Endless List like Android Market
Taking inspiration from Android Market, i have implemented a Endless List which loads more data from the serv开发者_如何学编程er when we reach the end of the List.
Now, i need to implement the progressbar & "Loading.." text as shown
Sample code to take inspiration from would be great.
Here is a solution that also makes it easy to show a loading view in the end of the ListView while it's loading.
You can see the classes here:
https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/helper/ListViewWithLoadingIndicatorHelper.java - Helper to make it possible to use the features without extending from SimpleListViewWithLoadingIndicator.
https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/listener/EndlessScrollListener.java - Listener that starts loading data when the user is about to reach the bottom of the ListView.
https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/view/SimpleListViewWithLoadingIndicator.java - The EndlessListView. You can use this class directly or extend from it.
Add an onScrollListener to the ListView. When the user scrolls, check if the ListView is nearing its end. If yes, then fetch more data. As an example :
public abstract class LazyLoader implements AbsListView.OnScrollListener {
private static final int DEFAULT_THRESHOLD = 10 ;
private boolean loading = true ;
private int previousTotal = 0 ;
private int threshold = DEFAULT_THRESHOLD ;
public LazyLoader() {}
public LazyLoader(int threshold) {
this.threshold = threshold;
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
if(loading) {
if(totalItemCount > previousTotal) {
// the loading has finished
loading = false ;
previousTotal = totalItemCount ;
}
}
// check if the List needs more data
if(!loading && ((firstVisibleItem + visibleItemCount ) >= (totalItemCount - threshold))) {
loading = true ;
// List needs more data. Go fetch !!
loadMore(view, firstVisibleItem,
visibleItemCount, totalItemCount);
}
}
// Called when the user is nearing the end of the ListView
// and the ListView is ready to add more items.
public abstract void loadMore(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount);
}
Activity :
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
ListView listView = (ListView) findViewById(R.id.listView);
listView.setOnScrollListener(new LazyLoader() {
@Override
public void loadMore(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
// Fetch your data here !!!
}
});
}
}
You can find the complete implementation at this link
The other answers here refer to outdated, unmaintained solutions. This article, however, seems to be kept up-to-date: https://github.com/codepath/android_guides/wiki/Endless-Scrolling-with-AdapterViews-and-RecyclerView
There's too much there to put it all in a SO answer, but here's some important bits as of the time I'm writing this answer:
Implementing endless pagination for
RecyclerView
requires the following steps:
- Copy over the EndlessRecyclerViewScrollListener.java into your application.
- Call
addOnScrollListener(...)
on aRecyclerView
to enable endless pagination. Pass in an instance ofEndlessRecyclerViewScrollListener
and implement theonLoadMore
which fires whenever a new page needs to be loaded to fill up the list.- Inside the aforementioned
onLoadMore
method, load additional items into the adapter either by sending out a network request or by loading from another source.To start handling the scroll events for steps 2 and 3, we need to use the
addOnScrollListener()
method in ourActivity
orFragment
and pass in the instance of theEndlessRecyclerViewScrollListener
with the layout manager as shown below:public class MainActivity extends Activity { // Store a member variable for the listener private EndlessRecyclerViewScrollListener scrollListener; @Override protected void onCreate(Bundle savedInstanceState) { // Configure the RecyclerView RecyclerView rvItems = (RecyclerView) findViewById(R.id.rvContacts); LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this); rvItems.setLayoutManager(linearLayoutManager); // Retain an instance so that you can call `resetState()` for fresh searches scrollListener = new EndlessRecyclerViewScrollListener(linearLayoutManager) { @Override public void onLoadMore(int page, int totalItemsCount, RecyclerView view) { // Triggered only when new data needs to be appended to the list // Add whatever code is needed to append new items to the bottom of the list loadNextDataFromApi(page); } }; // Adds the scroll listener to RecyclerView rvItems.addOnScrollListener(scrollListener); } // Append the next page of data into the adapter // This method probably sends out a network request and appends new data items to your adapter. public void loadNextDataFromApi(int offset) { // Send an API request to retrieve appropriate paginated data // --> Send the request including an offset value (i.e `page`) as a query parameter. // --> Deserialize and construct new model objects from the API response // --> Append the new data objects to the existing set of items inside the array of items // --> Notify the adapter of the new items made with `notifyItemRangeInserted()` } }
精彩评论