Reputation: 4629
I know there are a tonne of answers on SO for this but I can't seem to get it working how I'd like. I have a SherlockFragment
containing a ListView
which is populated by some data retrieving from a file. I've added a refresh button to the Fragment, the idea being that when you press it it retrieves any changes in the file and adds them to the view if necessary. I also added the popular PullToRefresh library.
Unfortunately, nothing changes however when I reload the Fragment (for example, rotating the device) I can see the new data. I've read about notifyDataSetChanged()
but it isn't working for me. The only thing I've gotten working is calling mPager.notifyDataSetChanged()
from my main FragmentActivity class and having the following set in my ViewPager adapter:
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
This accomplishes what I want, but it's not very sleek about it, and you can see it forcing the reload as it were. I'm currently using PullToRefresh and it forces it off page abruptly and quite frankly it just looks bad. To put it bluntly I need to call onCreateView
of my Fragment from my AsyncTask reloading the data.
If needed I'll post code, there's just a lot of it so I wouldn't want to post anything unneeded.
Oh, and please note I tried notifyDataSetChanged()
in the onPostExecute()
of my task.
Thanks for any guidance.
Upvotes: 1
Views: 6408
Reputation: 4629
I found a way around this but it's not perfect, so I won't accept this in case something better comes along.
Because upon return to my Fragment onResume()
is called (this answer is also pretty specific to my project), I just did the following:
@Override
public void onResume(){
super.onResume();
// Make the adapter again
adapter = new FeedListAdapter(this, feed);
// Set it to the list again
list.setAdapter(adapter);
}
This refreshes the list (badly) and is still fairly noticeable, although if I use a button instead of PullToRefresh it isn't.
My solution (however bad) alongside PullToRefresh is to stick it in a handler with a delayed trigger to let the pulled down "refresh" section disappear before it runs.
@Override
public void onResume(){
super.onResume();
new Handler().postDelayed(new Runnable() {
public void run() {
adapter = new FeedListAdapter(this, feed);
list.setAdapter(adapter);
}
}, 500);
}
Again, this is pretty specific to my project and a very strange way of doing it, so any "perfect" answer please share :)
EDIT: There was still an issue with it being a bit jumpy with PullToRefresh, so my solution was to wait in a new thread until the PullToRefresh is hidden again, then rebuild the list (it's messy, but it works so whatever):
@Override
public void onResume(){
super.onResume();
// Start a new thread
new Thread(new Runnable() {
@Override
public void run() {
try {
// Wait until the PullToRefresh is hidden
synchronized(this){
wait(190);
}
} catch(InterruptedException ex) { }
// Post a new runnable
threadHandler.post(new Runnable(){
public void run(){
// Recreate the adapter from the new feed
adapter = new FeedListAdapter(FeedListActivity.this, feed);
// Set the recreated adapter
list.setAdapter(adapter);
}
});
}
}).start();
}
}
EDIT 2:
Just noticed I missed something obvious. I just changed my list.onRefreshComplete();
for the PullToRefresh view to my onResume()
and the jumpiness was taken care of. Still, I think the above solution is more impressive :p
So my code:
@Override
public void onResume(){
super.onResume();
// Recreate the adapter from the new feed
adapter = new FeedListAdapter(this, feed);
// Set the recreated adapter
list.setAdapter(adapter);
// The list has finished refreshing
list.onRefreshComplete();
}
Upvotes: 1