Reputation: 685
EDIT: ((ArrayAdapter) getListAdapter()).notifyDataSetChanged(); doesn't work - I think it's an issue to do with me refreshing the entire list instead of just adding new entries but am unsure - if so how would I do this?
What is the correct way to retrieve data from my sqlite database and display it in a listactivity? My code which works (sort of) but doesn't refresh the list data properly after the first run is below. What I need to happen is:
Any help would be greatly appreciated!
public void populateStoryList() {
List<StoryItem> stories = datasource.getAllStoryItems();
if ( firstrun == true ) {
adapter = new StoryAdapter(this, stories);
setListAdapter(adapter);
firstrun = false;
} else {
// DON'T KNOW WHAT TO DO HERE
}
setProgressBarIndeterminateVisibility(false);
}
And the getAllStoryItems() function is as follows:
public List<StoryItem> getAllStoryItems() {
List<StoryItem> storyList = new ArrayList<StoryItem>();
Cursor cursor = database.query(StoriesTable.TABLE_STORIES,
allColumns, null, null, null, null, StoriesTable.COLUMN_DATE_APPROVED+" DESC");
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
StoryItem story = cursorToStoryItem(cursor);
storyList.add(story);
cursor.moveToNext();
}
// Make sure to close the cursor
cursor.close();
return storyList;
}
And the StoryAdapter:
import java.util.List;
import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
@SuppressWarnings("rawtypes")
public class StoryAdapter extends ArrayAdapter {
private final Activity activity;
private final List stories;
@SuppressWarnings("unchecked")
public StoryAdapter(Activity activity, List objects) {
super(activity, R.layout.story_row , objects);
this.activity = activity;
this.stories = objects;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
StoryAdapterView sView = null;
if(rowView == null)
{
// Get a new instance of the row layout view
LayoutInflater inflater = activity.getLayoutInflater();
rowView = inflater.inflate(R.layout.story_row, null);
// Hold the view objects in an object,
// so they don't need to be re-fetched
sView = new StoryAdapterView();
sView.title = (TextView) rowView.findViewById(R.id.title);
sView.story = (TextView) rowView.findViewById(R.id.story);
// Cache the view objects in the tag,
// so they can be re-accessed later
rowView.setTag(sView);
} else {
sView = (StoryAdapterView) rowView.getTag();
}
// Transfer the stock data from the data object
// to the view objects
StoryItem currentStock = (StoryItem) stories.get(position);
sView.title.setText(currentStock.getStoryTitle());
sView.story.setText(currentStock.getStoryText());
return rowView;
}
protected static class StoryAdapterView {
protected TextView title;
protected TextView story;
}
}
And last of all the StoryItem:
public class StoryItem {
private String dateApproved;
private String storyTitle;
private String storyText;
private long storyId;
private long storyOnlineId;
public StoryItem() {}
public StoryItem(String storyTitle, String storyText, String dateApproved, long storyId, long storyOnlineId) {
this.storyTitle = storyTitle;
this.storyText = storyText;
this.dateApproved = dateApproved;
this.storyId = storyId;
this.storyOnlineId = storyOnlineId;
}
public long getId() {
return storyId;
}
public void setId(long id) {
this.storyId = id;
}
public long getOnlineId() {
return storyOnlineId;
}
public void setOnlineId(long online_id) {
this.storyOnlineId = online_id;
}
public void setStoryTitle(String storyTitle) {
this.storyTitle = storyTitle;
}
public String getStoryTitle() {
return storyTitle;
}
public void setStoryText(String storyText) {
this.storyText = storyText;
}
public String getStoryText() {
return storyText;
}
public void setDateApproved(String dateApproved) {
this.dateApproved = dateApproved;
}
public String getDateApproved() {
return dateApproved;
}
}
Upvotes: 0
Views: 625
Reputation: 14037
What is the purpose of the firstRun
variable? I'm sure it should be removed, then everything will work fine.
Also I would rewrite your method like this:
public void populateStoryList() {
setProgressBarIndeterminateVisibility(true);
if (this.adapter == null) {
// first time, because adapter = null
List<StoryItem> stories = datasource.getAllStoryItems();
this.adapter = new StoryAdapter(this, stories);
setListAdapter(this.adapter);
} else {
List<StoryItem> newStories = datasource.getOnlyNewStoryItems();
for (StoryItem story : newStories) {
this.adapter.insert(story, 0);
}
// of course you can clear all items and replace them entirely, but it is not good for performance, so I don't recommend to use the commented code
//List<StoryItem> stories = datasource.getAllStoryItems();
//this.adapter.clear();
//for (StoryItem story : stories) {
// this.adapter.add(story);
//}
}
setProgressBarIndeterminateVisibility(false);
}
You must write the method getOnlyNewStoryItems
.
And it is obvious that the notifyDataSetChanged
method will not work and you don't need it here. It is used just for redrawing existing items without changing them, whereas you want to add new items and change the structure of the list.
Upvotes: 1