I have an Activity Class with an inner protected class that extends AsyncTask. I am trying to have the AsyncTask load data in background when I click a button and then display a list based on that data.
here is my code for the setListAdapter:
setListAdapter(new ArrayAdapter<String>(this, R.layout.list_row,
R.id.rowtextview, testArr.toArray(test2)));
the problem is that I can't just stick setListAdapter into the AsyncTask class because it needs a context for the outer class, and the only place it can go is inside the onCreate() in the outer Activity class. If its inside the onCreate, it can only be used once and isnt dynamic. I am not sure how I would go about making the list re-load every time I click a button and search for something new.
Your custom inner AsyncTask is not marked as static right? That means that it actually holds reference to the parent class, which is you Activity. So you can use:
setListAdapter(new ArrayAdapter<String>(YourActivity.this, R.layout.list_row,
R.id.rowtextview, testArr.toArray(test2)));
Easy, make the adapter an instance variable and extend it (trivial) to add your custom updateData(newData) method. In this method you update your data AND call notifyDatasetChanged(). And you're done! That way you only need to set the adapter once and just call updateData() when the AsyncTask comes back.
Related
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?
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.
I am new to Android programming, but not to programming in general or Java. My question here is mainly about best practices.
I created a class MenuListActivity that extends a ListActivity that shows menu items in a list and starts another Activity when clicked. Each menu is a child class of the MenuListActivity class and implements a getMenuItems() method to create the menu items.
In my onCreate() method, I call that getMenuItems() to create a MenuListAdapter class that is then set as the adapter of the ListActivity's ListView.
However, sometimes I get an illegalStateException telling me that "The content of the adapter has changed but ListView did not receive a notification.". Notice it happens sometimes, not all the times. I do not touch the adapter in any other thread, in fact the adapter is set like this:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ArrayList<MenuAdapterItem> menuItems = getMenuItems();
this.setListAdapter(new MenuAdapter(this, menuItems));
}
Another possibility I can think of, is to create an Adapter member variable and call notifyDataSetChanged() on each update.
What would be the way to do this correctly? (And hopefully fix my crashes ;-)).
Regards
Bart
i ran into this problem before and i used "setNotifyOnChange(true);" hope that helps.
I've got a ListView in my activity that is initially set to some Adapter. Then, after a certain button is clicked, I simply call listView.setAdapter(new DifferentAdapter(this, foo));
Seems to work just fine at first. The UI is updated and all is well. Then eventually, it crashes and the log shows me this:
E/AndroidRuntime(29724): java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. [in ListView(2, class android.widget.ListView) with Adapter(class android.widget.HeaderViewListAdapter)]
I'm guessing it's not so simple to simply call setAdapter() whenever you want. Do I need notifyDataSetChanged or something? If it matters, I'm not using a ListActivity.
EDIT
Clarification from below: It's pretty straightforward. I have two inner classes in my Activity, each of which extends BaseAdapter. So I've got two different Adapters and at some point I simply want to switch the ListView to use a different Adapter.
Apparently this works fine:
listView.setVisibility(View.GONE);
listView.setAdapter(new MyAdapter(MyActivity.this, mList));
listView.setVisibility(View.VISIBLE);
I have an activity which shows a Spinner (selection of category of items), a listview to show the orders and another listview -articles- which dynamically gets filled with buttons according to the selected category (spinner).
When an article button gets clicked, I want to add the article to the orderAdaptor.
How can I get a reference to the list adapter when I'm in the View.OnClickListener?
You'll need to post your code to get decent help with this, but it sounds like you are implementing the View.OnClickListener as an anonymous inner class inside of your Activity.
You can generally always get to the adapter by fully qualifying the reference:
MyActivity.this.mListView.getAdapter();
where MyActivity is a presumed class name that extends Activity and holds a member ListView named mListView.
You can pass it to your onClickListener's constructor and keep it in a member variable on the listener, or you can use setTag on the view to stash a reference to the adapter in the button and then retrieve it in the onClick listener with getTag. Or you could make the view listener a non-static inner class on your activity and access the adapter the same way everything else in your activity does (although I'd usually prefer being explicit and keeping the listener static / in a different class).