ListFragment and asynctask issues android - android

I am trying to display a list fragment in the middle of my activity. The list fragment adapter is a custom adapter (extended from BaseAdapter) with the typical ViewHolder pattern. It is implemented correctly.
I have the adapter set up with greenrobot Eventbus to receive a new List object from an asynctask which does the query in the background (as not to slow down the UI Main Thread).
The problem is the list fragment doesn't have the results of the database query initially so it defaults to empty (and displays the textview in my xml for the main activity which has the id 'empty').
In the end, my adapter, and listviewfragment don't get instaniated at all because it defaults to empty.
Is there a better method to doing this?
How can I get my listview fragment to wait for the data recieved from the asyncTask?
I am going to just do a fragment with a listview in it, instead of a listview fragment, and I'll see if that will help.

As I understood correctly, you did everything okay so far. What you have to do is to add an "update" method to your adapter, and call this whenever your asynctask finished it's job and got the results for you.
This update method should look something like
public void updateAdapterData(List<String> newList) {
mItems.clear(); // say mItems is the global list you have in the adpater
mItems.addAll(newList);
notifyDataSetChanged(); // This will cause the adpater to re-draw it's rows, so now data should be visible in your list
}
And in your fragment you do somehting like:
adpater.updateAdapterData(newList);
Does this help?

Related

How can I refresh ListView after deleting value from DB? [duplicate]

I'm trying to use in my Android Application the notifyDataSetChanged() method for an ArrayAdapter but it doesn't work for me.
I found as answer here, that notifyDataSetChanged() should run in the main thread, but there was no example for that.
Could anybody send an example or at least a link?!
For an ArrayAdapter, notifyDataSetChanged only works if you use the add(), insert(), remove(), and clear() on the Adapter.
When an ArrayAdapter is constructed, it holds the reference for the List that was passed in. If you were to pass in a List that was a member of an Activity, and change that Activity member later, the ArrayAdapter is still holding a reference to the original List. The Adapter does not know you changed the List in the Activity.
Your choices are:
Use the functions of the ArrayAdapter to modify the underlying List (add(), insert(), remove(), clear(), etc.)
Re-create the ArrayAdapter with the new List data. (Uses a lot of resources and garbage collection.)
Create your own class derived from BaseAdapter and ListAdapter that allows changing of the underlying List data structure.
Use the notifyDataSetChanged() every time the list is updated. To call it on the UI-Thread, use the runOnUiThread() of Activity.
Then, notifyDataSetChanged() will work.
You can use the runOnUiThread() method as follows. If you're not using a ListActivity, just adapt the code to get a reference to your ArrayAdapter.
final ArrayAdapter adapter = ((ArrayAdapter)getListAdapter());
runOnUiThread(new Runnable() {
public void run() {
adapter.notifyDataSetChanged();
}
});
I recently wrote on this topic, though this post it old, I thought it will be helpful to someone who wants to know how to implement BaseAdapter.notifyDataSetChanged() step by step and in a correct way.
Please follow How to correctly implement BaseAdapter.notifyDataSetChanged() in Android or the newer blog BaseAdapter.notifyDataSetChanged().
I had the same problem and I prefer not to replace the entire ArrayAdapter with a new instance continuously. Thus I have the AdapterHelper do the heavy lifting somewhere else.
Add this where you would normally (try to) call notify
new AdapterHelper().update((ArrayAdapter)adapter, new ArrayList<Object>(yourArrayList));
adapter.notifyDataSetChanged();
AdapterHelper class
public class AdapterHelper {
#SuppressWarnings({ "rawtypes", "unchecked" })
public void update(ArrayAdapter arrayAdapter, ArrayList<Object> listOfObject){
arrayAdapter.clear();
for (Object object : listOfObject){
arrayAdapter.add(object);
}
}
}
I know this is a late response but I was facing a similar issue and I managed to solve it by using notifyDataSetChanged() in the right place.
So my situation was as follows.
I had to update a listview in an action bar tab (fragment) with contents returned from a completely different activity. Initially however, the listview would not reflect any changes. However, when I clicked another tab and then returned to the desired tab,the listview would be updated with the correct content from the other activity. So to solve this I used notifyDataSetChanged() of the action bar adapter in the code of the activity which had to return the data.
This is the code snippet which I used in the activity.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId())
{
case R.id.action_new_forward:
FragmentTab2.mListAdapter.notifyDataSetChanged();//this updates the adapter in my action bar tab
Intent ina = new Intent(getApplicationContext(), MainActivity.class);
ina.putExtra("stra", values1);
startActivity(ina);// This is the code to start the parent activity of my action bar tab(fragment).
}
}
This activity would return some data to FragmentTab2 and it would directly update my listview in FragmentTab2.
Hope someone finds this useful!

How to update adapter items in viewpager

I have viewPager() which have 3 pages, it have a recyclerView and each page have three different adapters and i want something like when user clicks on adapter item in first page it adds in a database and second adapter gets its array list from the same database, but it shows in second page's adapter after app restarts, so the question is how to update the second page's adapter without restart.
A regular ListView can use a CursorAdapter which provides some of the functions you need. Alas, there is no existing CursorAdapter class that extends RecyclerView.Adapter.
The quickest solution would be to use RecyclerViewCursorAdapter on GitHub.
Then it would work something like this:
Update your database
Get a reference to your second page fragment. You can store this reference when you create the fragment in getItem(). Note that your fragment could be null depending on what pages the ViewPager has/hasn't created.
Call a method on your fragment that will create a new Cursor to be used by the adapter (with the same query as before). When the adapter receives the new Cursor it will update the RecyclerView.

updating a nested adapter does not update UI

I have a Fragment that contains a ListView that uses a custom adapter that extends ArrayAdapter. Each item in this list view, contains another ListView that also extends ArrayAdapter. Think of it as a list of news stories and each news story having multiple images.
I now want to add a new image to a news story. What I do is:
ImageAdapter imageAdapter =
newsAdapter.getImageAdapterForNewsItem(id);
imageAdapter.add(imageId);
imageAdapter.notifyDataSetChanged();
This all happens in SelectImagesFragment, where as the news items are listed in the NewsItemsFragment. However, the SelectImagesFragment contains a reference to the NewsItemsFragment. The above code executes in an AsyncTask, and before it executes, I move the user back to the NewsItemsFragment.
I was expecting the news list to get updated, once the AsyncTask completes and the UI to get refreshed. However, this is not happening. Since the ImageAdapter is inside the NewsAdapter, do I need to somehow tell the NewsAdapter that there has been a data change as well? If so, how do I do this? Calling 'notifyDataSetChanged()' won't work, since I didn't modify the underlying list data in NewsAdapter using add().

Populating ListView inside Fragment class extending ListFragment

I have a fragment class extending ListFragment and I'm having trouble populating the list.
I run an asynctask to retreive and parse data from a webservice which is all working ok but now I'm stuck on where I should set the list adapter to populate my list.
I am currently executing my asynctask in the onCreate() method and trying to populate the list in onActivity created which gives a NullPointerException. If i remove the setListAdapter everything runs fine.
According to the android developer docs, a fragment extending ListFragment returns a ListView from onCreateView() by default so I should have access to it.
Where is the correct place to set my list adapter to populate the list?
Thanks for your help.
You are going to want to set the list adapter in the onPostExecute() in the AsyncTask. You can pass a reference to the ListFragment into the constructor for AsyncTask and call setListAdapter() on that reference.

how to refresh the elements in a adapter without starting a new activity?

I have the following situation:
I have a singleton controller which contains a List<Foo>
when my activity starts I load the items to my BaseExpandableListAdapter
the problem: When I now delete a item form the singleton List it gets net deletet in the view. Only when I start the whole activity again. How to solve this without starting the whole activity again?
public void notifyDataSetChanged ()
Added in API level 1
Notifies the attached observers that the underlying data has been changed and any View reflecting the data set should refresh itself.
http://developer.android.com/reference/android/widget/ArrayAdapter.html#notifyDataSetChanged%28%29
When you change the database that is used by the adapter, you should call notifyDataSetChanged() on the adapter.

Categories

Resources