This post describes how to use an Android Listview endless adapter. There are some situations where an Android app with a ListView have to load new data as the user scrolls down. This is the case of an endless adapter. An endless adapter, in other words, is an adapter that loads more data when a user reaches the ListView end. This kind of adapter is useful when there is a large number of items and we don’t want to show them all to avoid a long loading time. This post explains how to implement it.
To implement a Listview endless adapter it is necessary:
- a custom listview
- a listener
- a custom adapter
If you prefer to download the Android app source code directly you can use this link:
In this case, the custom adapter is very simple and we can replace it with something more complex or use the standard android adapter.
Custom Listview endless adapter component
To implement an Android Listview endless adatper it is necessary to code a component that holds the business logic. In this component, we have to find a way to check if the user scrolled all the item inside the ListView and he/she reached its end. Let us begin.
The first step is creating a custom component so we can extend the standard ListView behavior.
[java]public class EndlessListView extends ListView implements OnScrollListener {..
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
…
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {}
}[/java]
At line 1, we extends ListView and implements OnScrollListener to get notified when the user scrolls on the ListView. At line 4, we override onScroll method, called during the scroll. When we reach the ListView end we have to show a view that informs the user to wait until the all the data is loaded. We can use a “trick” to show the wait indicator, we can exploit the ListView footer. We can add and remove it as we need. To make our component configurable we can simply set a view to use a footer:
[java]public void setLoadingView(int resId) {LayoutInflater inflater = (LayoutInflater) super.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
footer = (View) inflater.inflate(resId, null);
this.addFooterView(footer);
}[/java]
Let’s focus on the onScroll method. Here we have to check if the firstVisibleElement plus itemCounts (the number of items show inside the ListView) is greater that the total number of items. If this condition is verified then we can fire the event to load more data:
[java]@Overridepublic void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
if (getAdapter() == null)
return ;
if (getAdapter().getCount() == 0)
return ;
int l = visibleItemCount + firstVisibleItem;
if (l <= totalItemCount && !isLoading) {
// It is time to add new data. We call the listener
this.addFooterView(footer);
isLoading = true;
listener.loadData();
}
}
[/java]
At line 12, we simply add the footer to inform the user we are loading more data, then at line 13, we set a true a boolean attribute to not fire the event again while we are still loading the data and then we call the listener.
As you can see the listener is very simple:
public void loadData() ;
}[/java]
Just one more thing, when the loading data process is finished our custom ListView must be informed so that we can refresh the items and remove the footer:
[java]public void addNewData(List<String> data) {this.removeFooterView(footer);
adapter.addAll(data);
adapter.notifyDataSetChanged();
isLoading = false;
}[/java]
At line 4, we call notifyDataSetChanged to inform the adapter that the dataset is changed.
Test Listview endless adapter: component
To test the custom component we can create a simple layout including our custom ListView:
[xml]<RelativeLayout xmlns:android=”http://schemas.android.com/apk/res/android”xmlns:tools=”http://schemas.android.com/tools”
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:paddingBottom=”@dimen/activity_vertical_margin”
android:paddingLeft=”@dimen/activity_horizontal_margin”
android:paddingRight=”@dimen/activity_horizontal_margin”
android:paddingTop=”@dimen/activity_vertical_margin”
tools:context=”.MainActivity”>
<com.survivingwithandroid.endlessadapter.EndlessListView android:id=”@+id/el”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content” />
</RelativeLayout>
[/xml]
and we need a main activity so that :
[java]@Overrideprotected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = (EndlessListView) findViewById(R.id.el);
EndlessAdapter adp = new EndlessAdapter(this,
createItems(mult), R.layout.row_layout);
lv.setLoadingView(R.layout.loading_layout);
lv.setAdapter(adp);
lv.setListener(this);
}[/xml]</pre>
At line 7, we set the footer view then at the line the adapter and at the end we set our activity as a listener for our custom ListView. To emulate the internet loading data, we can simply create an AsyncTask and make our thread sleeps for some seconds. Notice that in the onPostExecute:
<pre>[java]@Override
protected void onPostExecute(List<String> result) {
super.onPostExecute(result);
lv.addNewData(result);
}[/java]
At line 4, we add the new loaded data.
Summary
At the end of this post, you learned how to use a custom adapter to build an endless ListView.
I think this is EndLess ListView Rather than Endless adapter.
@AddictiveBlogs.com I agree with you
My relatives all the time say that I am wasting my time here at
net, but I know I am getting experience all the time by reading thes good
articles.