I am trying to use PulltoRefresh and EndlessAdapter, the first time that the app run, the list loads very well, but when it gets in the end to load more data, it crash.
Library EndLessAdapter: https://github.com/commonsguy/cwac-endless
Library PulltoRefresh: https://github.com/chrisbanes/Android-PullToRefresh
It was working without PullToRefresh.
First time that app run, it calls:
- getPendingView
- MyAsyncTask
- return hasmoredata
- Call postOnExecute - listener
- Call OnItemsReady
- Set DemoAdapter.notydatasetchanged
When it get the end of list, then it calls:
- getPendingView
- MyAsyncTask
- return hasmoredata
- Gives IndexOutofBoundException
StackTrace:
01-28 11:12:15.273: E/AndroidRuntime(12735): FATAL EXCEPTION: main
01-28 11:12:15.273: E/AndroidRuntime(12735): java.lang.IndexOutOfBoundsException: Invalid index 1, size is 1
01-28 11:12:15.273: E/AndroidRuntime(12735): at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:257)
01-28 11:12:15.273: E/AndroidRuntime(12735): at java.util.ArrayList.get(ArrayList.java:311)
01-28 11:12:15.273: E/AndroidRuntime(12735): at android.widget.HeaderViewListAdapter.getView(HeaderViewListAdapter.java:225)
01-28 11:12:15.273: E/AndroidRuntime(12735): at android.widget.AbsListView.obtainView(AbsListView.java:1592)
01-28 11:12:15.273: E/AndroidRuntime(12735): at android.widget.ListView.makeAndAddView(ListView.java:1782)
01-28 11:12:15.273: E/AndroidRuntime(12735): at android.widget.ListView.fillDown(ListView.java:705)
Inside PullToRefreshListinViewPager sample:
public View instantiateItem(ViewGroup container, int position) {
PullToRefreshListView plv = null;
Context context = container.getContext();
plv = (PullToRefreshListView) LayoutInflater.from(context).inflate(
R.layout.layout_listview_in_viewpager, container, false);
endlessList = new ArrayList<HashMap<String, String>>();
demoAdapter = new DemoAdapter(context, endlessList);
demoAdapter.setRunInBackground(false);
plv.setAdapter(demoAdapter);
plv.setOnRefreshListener(BaseSampleActivity.this);
// Now just add ListView to ViewPager and return it
container.addView(plv, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
return plv;
}
EndLessAdapter:
private class DemoAdapter extends EndlessAdapter implements IItemsReadyListener{
private RotateAnimation rotate=null;
private View pendingView=null;
private ArrayList<HashMap<String, String>> data;
private List<HashMap<String, String>> mOriginalNames;
private boolean hasMoreData=true;
private Context mContext;
DemoAdapter(Context context, ArrayList<HashMap<String, String>> d) {
super(new LazyAdapter(context, d));
this.data = d;
this.mContext = context;
rotate=new RotateAnimation(0f, 360f, Animation.RELATIVE_TO_SELF,
0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
rotate.setRepeatMode(Animation.RESTART);
rotate.setRepeatCount(Animation.INFINITE);
}
@Override
protected View getPendingView(ViewGroup parent) {
View row = LayoutInflater.from(mContext).inflate(R.layout.row, null);
View child=row.findViewById(android.R.id.text1);
child.setVisibility(View.GONE);
child=row.findViewById(R.id.throbber);
child.setVisibility(View.VISIBLE);
child.startAnimation(rotate);
return(row);
}
@Override
protected boolean cacheInBackground() {
if(isNetworkOnline() == true){
new MyAsyncTask(this, data.size()).execute();
}
return hasMoreData;
}
public void onItemsReady(ArrayList<HashMap<String, String>> data) {
endlessList.addAll(data);
demoAdapter.onDataReady(); // Tell the EndlessAdapter to remove it's pending
// view and call notifyDataSetChanged()
hasMoreData = endlessList.isEmpty();
}
@Override
protected void appendCachedData() {
if (getWrappedAdapter().getCount()<75) {
@SuppressWarnings("unchecked")
LazyAdapter a=(LazyAdapter)getWrappedAdapter();
for (int i = 0; i < data.size(); i++) {
a.add(data.get(i));
}
}
}
}
AsyncTask:
private static class MyAsyncTask extends AsyncTask<Void,Void,ArrayList<HashMap<String, String>>>{
IItemsReadyListener listener;
int startPoint;
public MyAsyncTask(IItemsReadyListener listener, int startPoint) {
// TODO Auto-generated constructor stub
this.listener = listener;
this.startPoint = startPoint;
}
@Override
protected ArrayList<HashMap<String, String>> doInBackground(Void... params) {
XMLParser parser = new XMLParser();
String xml = parser.getXmlFromUrl(URL); // getting XML from URL
Document doc = parser.getDomElement(xml); // getting DOM element
NodeList nl = doc.getElementsByTagName(KEY_SONG);
// looping through all song nodes <song>
for (int i = 0; i < 10; i++) {
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
Element e = (Element) nl.item(i);
// adding each child node to HashMap key => value
map.put(KEY_ID, parser.getValue(e, KEY_ID));
map.put(KEY_TITLE, parser.getValue(e, KEY_TITLE));
map.put(KEY_ARTIST, parser.getValue(e, KEY_ARTIST));
map.put(KEY_DURATION, parser.getValue(e, KEY_DURATION));
map.put(KEY_THUMB_URL, parser.getValue(e, KEY_THUMB_URL));
// adding HashList to ArrayList
endlessList.add(map);
}
return (endlessList);
}
@Override
protected void onPostExecute(ArrayList<HashMap<String, String>> result)
{
listener.onItemsReady(endlessList);
// Getting adapter by passing xml data ArrayList
if (demoAdapter != null)
{
demoAdapter.notifyDataSetChanged();
}
}
}
UPDATE:
I just change:
@Override
protected boolean cacheInBackground() throws Exception {
if(isNetworkOnline() == true){
new MyAsyncTask(this).execute();
}
if (getWrappedAdapter().getCount()<75) {
return(true);
}
throw new Exception("Gadzooks!");
}
Now it loads more content, but after it loads 3 times and get into final, it throws the Exception Gadzooks and after it shows me the same IndexOutofBoundException.
I just know that every time that cacheinBackground return false, then it crash.