0

actually my problem is same as this guy's.But I don't know how to resolve it.Here's my listview xml file.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#FFFFFF">

<LinearLayout     android:orientation="horizontal"
                  android:layout_width="fill_parent"
                  android:layout_height="wrap_content"
                  android:weightSum="3"
                  android:background="#CCCCCC"
                  android:id="@+id/tabs">

    <Button 
           android:layout_width="fill_parent"
           android:layout_height="wrap_content"
           android:layout_weight="1"
           android:background="#CCCCCC"
           android:textSize="20sp"
           android:textColor="#000000"
           android:text="@string/NewTask"
           android:id="@+id/tab1"
        />

    <Button 
           android:layout_width="fill_parent"
           android:layout_height="wrap_content"
           android:background="#CCCCCC"
           android:layout_weight="1"
           android:textSize="20sp"
           android:textColor="#000000"
           android:text="@string/Friends"
           android:id="@+id/tab2"
        />
    <Button 
           android:layout_width="fill_parent"
           android:background="#CCCCCC"
           android:layout_height="wrap_content"
           android:textColor="#000000"
           android:layout_weight="1"
           android:text="@string/AddPeople"
           android:textSize="20sp"
           android:id="@+id/tab3"
        />
    </LinearLayout>

<ListView
    android:id="@android:id/list"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:cacheColorHint="#000000"
    android:layout_below="@+id/tabs"
/>

</RelativeLayout>

I am trying to call a function in my listactivity from the onpostExecute of my AsyncTask class. Here's the function of my listactivity.

public void SetImage(Bitmap bmp,int index)
{
    View v = this.ls.getChildAt(index);
    ImageView img = (ImageView)v.findViewById(R.id.tasks_userimg);
    img.setImageBitmap(bmp);
}

This bmp is the bitmap downloaded in the asynctask class and ls is the listview and the index is the index of the item in the listview.When the postexecute runs I call this function with the arguments to update the listview item image.

The problem is exactly same as I've mentioned in the link i.e when I scroll it gives me error.But he solved the problem by changing the layout width of listview but it is not working here.

Community
  • 1
  • 1
Mj1992
  • 3,404
  • 13
  • 63
  • 102

2 Answers2

0

Seems that like many others , you have some problems with this special view .

I highly recommend watching the lecture "the world of listView".

They talk about a lot of topics related to listView , including the topic of calling getView multiple times on the same view. In short , the reason why it occurs is because getView is also called for measuring the listView items . You can use (and should) use the convertView in order to avoid un-needed inflating and fetching of data .

About the question itself , you should not use findViewById on the listView items , since they are getting re-used . For example , a view that was set for the 0-th position may be set to the 7-th position in case the user has scrolled down .

if you wish to update a single item from the listView , you can use something like this:

// itemIndex is the index of the item to update
final View v=listView.getChildAt(itemIndex-listView.getFirstVisiblePosition());
//now you update your view according to what you wish . 
//you must of course handle the cases that you can't get the view .

Of course , once you do it , you will also have to update your data behind the adapter , so that the next time the user scrolls to this item , it will have the bitmap shown to it.

What you should do depends on the asyncTask you've used .

I assume that you download multiple bitmaps while the listview fills its items . If that's the case , check out this sample , or use my suggestion : have an asyncTask for each viewHolder you have . For each time getView is called , cancel the old one and create a new one for the current item.

android developer
  • 114,585
  • 152
  • 739
  • 1,270
  • you're exactly right.I am trying to get a single listview item and update its image.I am doing so because I am loading multiple images in async task which get's loaded late, so I keep their index in the async task class and `onpostexecute` i pass that index to update that item in the listview. – Mj1992 Feb 07 '13 at 20:57
  • In case you download multiple bitmaps , I highly recommend having some sort of caching mechanism , and if it's a lot of images , try to download only those that you need (or a lot of them each time there are new images to get, but still not all) . Consider using a caching mechanism that involves both memory and storage. – android developer Feb 07 '13 at 21:00
  • But the `itemIndex-listView.getFirstVisiblePosition()` will load the first visible item on the screen, if i am correct then if user scrolled and some other item is on top the image will be loaded for that item although it is not of that item. So how would I exactly point to that list item through its index. – Mj1992 Feb 07 '13 at 21:04
  • As i've written, this should only be used in case you want to update a single item in the listView . so of course you shouldn't update it while scrolling . For most cases , you should use getView . I've written about the other topics since i wasn't sure about what you need. – android developer Feb 07 '13 at 22:04
0

1) Define your custom adapter

2) Apply holder pattern

3) Use some image uploader (for example this)

Take a look simple example

Georgy Gobozov
  • 13,633
  • 8
  • 72
  • 78