tags:

views:

90

answers:

2

Hi all,

I have a list (ListView) which displays news items. They contain a image, title and some text. The image is loaded in a separate thread (with a queue and all) and when the image is downloaded, I now call notifyDataSetChanged() on the list adapter to update the image. This works, but getView() is getting called way to often now, since notifyDataSetChanged() calls getView() for all visible items. I want to update just the single item in the list. How would I do this?

Problems I have with my current approch is that the list is slow and I have a fadein animation on the image which happens every time a single new image in the list is loaded.

Thanks a lot, Erik

A: 

This question has been asked at the Google I/O 2010, you can watch it here:

The world of ListView, time 52:30

Basically what Romain Guy explains is to call getChildAt(int) on the ListView to get the view and (I think) call getFirstVisiblePosition() to find out the correlation between position and index.

Romain also points to the project called Shelves as an example, I think he might mean the method ShelvesActivity.updateBookCovers(), but I can't find the call of getFirstVisiblePosition().

Please let me know how you did it, because this also is interesting to me! :-)

mreichelt
I posted the solution. Thanks for your info!
Erik
Good thing! :) Maybe you can add a null check here, too - v may be null if the view is not available in the moment. And of course this data will be gone if the user scrolls the ListView, so one should also update the data in the adapter (perhaps without calling notifyDataSetChanged()). In general I think it would be a good idea to keep all this logic within the adapter, i.e. passing the ListView reference to it.
mreichelt
+2  A: 

I found the answer, thanks to your information mreichelt. You can indeed get the right view using View#getChildAt(int index). The catch is that it starts counting from the first visible item. In fact, you can only get the visible items. You solve this with ListView#getFirstVisiblePosition().

Example:

private void updateView(int index){
    View v = yourListView.getChildAt(index - yourListView.getFirstVisiblePosition());
    TextView someText = (TextView) v.findViewById(R.id.sometextview);
    someText.setText("Hi! I updated you manually!");
}
Erik