How to instance a custom ArrayAdapter during the doInBackground of an AsyncTask? - android

i have a listview with a custom arrayadapter. each row of the list have also a gallery with her own adapter. so everything works fine. but scrolling fast the list, it stagnates because each row must load the the secound adapter of the gallery. this are only millisecounds, but you feel ist, because the list don't scroll smooth. so i would like to load the secound arrayadapter of the gallery in an asynctask, so that the scrolling in not influence. but their is the problem:
in the doInBackground-method i want to do this:
CustomAdapter customAdapter = new CustomAdapter(activity, R.layout.items, arraylist);
but there he throws me a futuretask error. i thing it is the "activity" that is the problem. can i solve it? or is their no chance?
I hope you can help me.
Thanks!

I think that the problem is that you are using non-reusable ListView adapters. Using them will improve application speed as it will reuse resources and you will avoid garbage collecting. Find out more at: http://www.softwarepassion.com/android-series-custom-listview-items-and-adapters/, especially look at OrderAdapter implementation.
You won't be able to modify view in doInBackground as it is not invoked on the UI thread. Please refer to Android documentation: http://developer.android.com/reference/android/os/AsyncTask.html

Related

Android listview refresh only once

I am really desperate, please help me.
In my main Activity I want to remove all items from the listview then add other data. I am able to delete the data and refresh the listview, but when I add new data, something strange happens. I insert the data in my Array. I call notifydatasetchanged on my adapter after every insertion. The adapter gets those items (I have confirmed this in debug mode). But the listview will not refresh. And now comes the VERY STRANGE thing: When I tap the back button on my device, the application quits (this part is ok), but for a moment before quitting it refreshes the listview with the correct data.
Here are some parts of my code:
For deleting the data I use:
newsArrayList = new ArrayList<NewsClass>();
Adapter = new NewsAdapter(this, newsArrayList);
lv.setAdapter(Adapter);
"lv" is my listview. The listview correctly loses all items and refreshes. I have also tried this:
newsArrayList.clear();
Adapter.notifyDataSetChanged();
Also worked like expected. Then I use a "for" loop to add new items to my array, where I have the following lines:
newsArrayList.add(news[i]);
Adapter.notifyDataSetChanged();
As I wrote, when running in debug mode, everything seems fine. I have spent all day working on this problem. I have read several posts about similar issues on stackoverflow, I even watched a video on youtube. I am calling everything from the main UI thread.
I can work around this problem by restarting my activity, but I want to do it better than that. I have tried invalidate and such things, but nothing helped. Please note the VERY STRANGE thing, I wrote...
I think, that I have to force the activity to redraw its views, or something like that, but even refreshDrawableState(); on my listview did not help.
Thank you in advance!
Basically If you want to clear list data then just call
newsArrayList.clear();
lv.setAdapter(null);
Again add what ever your data in ArrayList and set adapter
newsArrayList = new ArrayList<NewsClass>();
Adapter = new NewsAdapter(this, newsArrayList); // considering list with some elements
lv.setAdapter(Adapter);
If you are getting outofmemory error/exception then there is problem with your Adapter Class inside getView method

What is more expensive? Creating a new ArrayAdapter every time the data changes or updating an existing ArrayAdapter?

To update a Listview we can do following two things:
1) Create a new ArrayAdapter and bind it to ListView everytime the data is updated.
this.listView.setAdapter(new ArrayAdapter(getActivity(), data));
or
2) Update the contents of ArrayAdapter which is already binded to listview:
this.arrayadapter.clear();
for (Data item : data)
this.arrayadapter.add(item);
this.arrayadapter.notifyDataSetChanged();
So which method is more expensive?
The way you are doing it, the second one is definitely more expensive. ArrayAdapter calls notifyDataSetChanged() internally in clear() as well as in add(). You could change it to
this.arrayadapter.setNotifyOnChange(false);
this.arrayadapter.clear();
for (Data item : data)
this.arrayadapter.add(item);
this.arrayadapter.setNotifyOnChange(true);
this.arrayadapter.notifyDataSetChanged();
But even if you it this way, both calls contain a synchronized block which makes them slow. So even though you are creating a new ArrayAdapter in the first method, I would say it is faster.
You could further optimize it by using a custom adapter with a setItems(data) method that just replaces the internal data list.
I'd becareful with the accepted answers final conclusion. While SimonSays makes valid points about the iteration and adding...there's a lot that happens with setting a new adapter he fails to recognize. Which makes it hard to say if it's actually any better then the suggested for...each approach.
Setting a new adapter will cause the ListView to flush out all it's recycled view's. It'll also have to re-measure all the new views coming in...which leads to the getView() being called 3-4 times per item for several of the positions...if not all positions. (Varies with platform). So even though there's a sync block on adding, you'll probably see the getView method invoked far less times with possibility of using recycled views.
Basically, knowing which is better is hard and depends greatly on use case. I'd vote to stick with the for...each approach simply for better readability.

Live Update ListView

I have dug deep down into SO but, although I have found other people asking similar questions to mine, I have not yet find a question that addresses the same issues I have. I have not found a satisfying answer either.
I have a ListView. When I call from the adapter, .notifyDataSetChanged, the ListView is updated, but I can see the update only once onResume() is called. In other words, I do not see it instantly, only after I leave the activity and comeback.
What can I do to see the update instantly? I have tried the .notifyDataSetChanged method, I have tried resetting the adapter... nothing worked.
According to your comment, you dont update the array IN the adapter, but an array held by the activity you passed to the adapter once. Thats why the adapter isnt updating properly. You are changing the array outside of your adapter-class, which might not be the same array-object your adapter is using. At onResume(), your adapter is recreated with the new array and showing the new content.
A solution would be using the following custom Adapter class:
class MyAdapter extends BaseAdapter {
private Array[] myArray;
public MyAdapter(Array[] myArray) {
this.myArray = myArray;
}
public updateContent(Array[] myNewArray) {
this.myArray = myNewArray;
this.notifyDataSetChanged();
}
// your getItem, getView, and so on methods
}
Then from your activity, simple call myArray.updateContent() with your new Array and it will update immediatly.
Its never good to hold and manipulate an object used from one class (the adapter) within another one (the activity). Try to move all code for manipulating the array into the adapter and use methods to add/remove items. This will make it a lot easier finding this kind of errors!

Couldn't clear an ArrayAdapter

I have a GridView backed by an ArrayAdapter. Everything works except for one thing: I couldn't clear that adapter (need this when refreshing the `GridView).
This is what I have:
adapter.clear();
adapter.notifyDataSetChanged();
Prior to this project I have never had any issue regarding adapter clearing. I can't find what I am doing wrong here.
Any idea? (don't hesitate to ask for specific details).
Thanks!
Problem solved.
I had to keep a reference on the collection that the adapter was taking its data from and then do:
myCollection.clean();
adapter.notifyDataSetChanged();

how to stop executing the getView() method while scrolling the ListView items using SimpleAdapter in android

i have used SimpleAdapter to display a list of items in a listview.While displaying the getView() is called every time to display every list item with different layout.Here i got succeeded in doing so.But here the problem is whenever i scroll the list items again the getView() method is executing and iam getting the unreliable results.Here my requirement is i dont want to execute the getView() method while scrolling the listview.Any body please guide me out of this situation.
This is the intended behaviour of the ListView, it is automatically buffered. So as you scroll, new items are inflated and added and the old ones are knocked off. This mechanism works by calling your overridden getView() method.
If you don't want this then just use a LinearLayout inside a scrollview and manually populate it with your list items. You can even still use your adapter by using:
linear.addView(adapter.getView(index, null, linear));
Hope this helps!
I want to add one thing that if
you have more than one records in your adapter just use a for loop like this.
ArrayAdapter<Question> adapter = MyCustomArrayAdapter
.GetArrayAdapterInstance(this, flag1, flag1, lst_question);
for(int i=0;i<adapter.getCount();i++)
{
linear.addView(adapter.getView(i, null, linear));
}
I also get the same problem, and here is our response !
Android, how to stop reading getView() function again, if the content is already downloaded in the ListView
Let me know if it work for you ;)

Categories

Resources