Each item in my ListView
containt an ImageView
and a TextView
, this will be filled with remote information.
I got an URL for the ImageView
, therefore I start an AsyncTask
which downloads the image and will call setImageBitmap
with the downloaded bitmap.
This goes very well but when the ListView is created, the getView()
is called to often.
It calls about 7 times the getView
for the first 10 rows (only 7 visible). (So: 0, 1, etc, 10, 0, 1 etc).
Then I can just scroll smoothly to the 10th item. But after that, for each new row the listview calls again about 7 times the getView
for the first 10 items. (This will cause lag..)
But when I remove the setImageBitmap
from the AsyncTask
, this all won't happen!
What could be the problem? Could it be that some layout is to big which will cause another streak of getViews ?
Here some code:
<ListView
android:id="@+id/mylist"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_alignParentBottom="true"
android:layout_below="@+id/mydivider"
android:divider="@+color/mycolor"
android:dividerHeight="2dp"
android:fadingEdge="none"
android:fastScrollEnabled="true"
android:listSelector="@android:color/transparent"
android:scrollbars="horizontal"
android:scrollingCache="false"
android:smoothScrollbar="false" />
The AsyncTask:
public static class MyTask extends AsyncTask<String, Integer, Bitmap> {
private LruCache<String, Bitmap> mMap;
private String mUri;
private int mPosition;
private ViewHolder mHolder;
public MyTask (ViewHolder holder, int position, LruCache<String, Bitmap> map) {
mMap = map;
mHolder = holder;
mPosition = position;
}
@Override
protected Bitmap doInBackground(String... url) {
mUri = url[0];
return getBitmapFromURL(mUri);
}
@Override
protected void onPostExecute(Bitmap b) {
if (b != null) {
mMap.put(mUri, b);
if (mPosition == mHolder.position) {
holder.image.setImageBitmap(b);
}
}
};
}
getView()
row = convertView;
ViewHolder holder;
if (row == null) {
row = vi.inflate(R.layout.mylayout, null);
holder = new ViewHolder();
holder.image = (ImageView) row.findViewById(R.id.myimage);
holder.title = (TextView) row.findViewById(R.id.mytext);
row.setTag(holder);
} else {
holder = (ViewHolder) row.getTag();
}
holder.title.setText("text");
holder.image.setImageResource(R.drawable.mydefaulticon);
holder.position = position;
startMyTask(content, holder, position);
Some more information:
When an new view is created the stacktrace shown the getView was called from ListView.makeAndAddView()
But in the useless streak of getViews it is coming from ListView.measureHeigthOfChildren()
So it seems like the layout is changed when I set the Bitmap...
The problem was in the Layout of the ListView.
The parameter layout_width
was set to wrap_content
when I changed it to fill_parent
the problem disappeared...
i recommend you to watch this video http://www.youtube.com/watch?v=wDBM6wVEO70
basically android will call getView multiple times for it's calculation of view heights and stuff, so you need to implement some sort of cache in your async, check http://code.google.com/p/android-query/ which has that if you don't use authentication
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With