I have a custom ListView that I fill with my custom ArrayAdapter. I read and parse json data from URLs and fill the ListView with this. It works perfectly when I read the first file. Now I want to be able to add more data (older posts) to my ListView, though. I've added a "Load More" button as a footer to the ListView, when I've loaded the new data though and try to scroll through it I get this error:
java.lang.IndexOutOfBoundsException: Invalid index 25, size is 25
At first I didn't understand at all why this was, now I realize it's that my ListView isn't expandable. When I search google for expandable ListViews the custom adapters extend BaseExpandableListAdapter, but I'm not sure how to implement that in my application.. My custom arrayadapter is defined like this:
private class StreamAdapter extends ArrayAdapter<Message>
Message being one of my classes.
This is how I display the data:
private void DisplayData() {
// If the request was successfull then notify the adapter to display the data
if(success) {
if(dataAdapter.isEmpty())
{
dataAdapter.addAll(dataList);
dataAdapter.notifyDataSetChanged();
}
// If the listview isn't empty we want to erase what's there and then add the older posts to display
else
{
/** Add currently displayed messages to a temporary arraylist, clear the listview, then add both arraylists in the correct order **/
int size = messageList.getTop();
ArrayList<Message> temp = new ArrayList<Message>();
for(int i = 0; i < size; i++)
{
temp.add(dataAdapter.getItem(i));
}
dataAdapter.clear();
temp.addAll(dataList);
dataAdapter.addAll(temp);
dataAdapter.notifyDataSetChanged();
}
}
}
The whole temp-ArrayList-thing was the only way I could come up with to get the newly loaded data (but oldest posts) at the bottom of the listview instead of at the top.
Is there any way to easily make my ListView expandable or do I have to rewrite my entire StreamAdapter class?
Kristina
EDIT: Here's the code for my StreamAdapter class, I left parts out though as I'm fairly sure it's not relevant and just adds to a bunch of code.
private class StreamAdapter extends ArrayAdapter {
public StreamAdapter(Context context, int textViewResourceId, ArrayList<Message> dataList)
{
super(context,textViewResourceId, dataList);
}
private class ViewHolder {
ImageView thumbnail;
TextView display_name;
TextView username;
TextView created_at;
TextView text;
ImageView comments;
TextView nr_comments;
@SuppressWarnings("unused")
ImageView like;
TextView nr_likes;
@SuppressWarnings("unused")
ImageView starred;
TextView nr_starred;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if(convertView == null)
{
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.data_row, null);
holder = new ViewHolder();
holder.thumbnail = (ImageView) convertView.findViewById(R.id.thumbnail);
holder.display_name = (TextView) convertView.findViewById(R.id.display_name);
holder.username = (TextView) convertView.findViewById(R.id.username);
holder.created_at = (TextView) convertView.findViewById(R.id.created_at);
holder.text = (TextView) convertView.findViewById(R.id.text);
holder.comments = (ImageView) convertView.findViewById(R.id.comments);
holder.nr_comments = (TextView) convertView.findViewById(R.id.nr_comments);
holder.like = (ImageView) convertView.findViewById(R.id.like);
holder.nr_likes = (TextView) convertView.findViewById(R.id.nr_likes);
holder.starred = (ImageView) convertView.findViewById(R.id.starred);
holder.nr_starred = (TextView) convertView.findViewById(R.id.nr_starred);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
final Message data = dataList.get(position);
holder.thumbnail.setImageDrawable(getResources().getDrawable(R.drawable.owl_thumbnail));
holder.display_name.setText(data.created_by.getDisplay_name());
holder.username.setText("@"+data.created_by.getUsername());
holder.created_at.setText(data.getCreated_at());
holder.nr_comments.setText(Integer.toString(data.getComments().length));
holder.nr_likes.setText(Integer.toString(data.getLiked_by().length));
holder.nr_starred.setText(Integer.toString(data.getStarred_by().length));
// Code to make certain text in the text-textview clickable
// Clickhandler for the username (display_name)
holder.display_name.setOnClickListener(new OnClickListener() {
// Code
});
// Clickhandler for comments
holder.comments.setOnClickListener(new OnClickListener() {
//Code
});
return convertView;
}
}
Instead of adding new data to adapter items try getting a reference to your data list from adapter and add this data into it for ex:
And in when you update it
This should work, try it and let me know.
Also override following function inside adapter
EDIT
EDIT 2