Listview Very Slow When Scrolling (using Viewholder/recycling)
Solution 1:
UPDATE 2011-08-29 If I remove the image in the NodePickup, the lagginess is gone.
The view has a hard time figuring how the layout should be rendered. The xml you posted don't help much. If you remove the ImageView then the LinearLayout02 will take all the width of the parent. But having the imageView with standar dimentions and the layout to the right will fill_parent confuses the view a lot. Requests the size of the imageView again to "push the margins to the right" (kind of). Take a look at my suggestions below
Tip1
use the LinearLayout property weight. Make the imageView fill_parent and the LinearLayout too (for the width) and play with the weight properties. Do that also for the vertical layout with the TextViews. The best Solution whould be to put a fixed size to the height of the TextViews thought. Also consider to change the top view to RelativeLayout. Make the image with standar dimentions , AlignParentLeft and put the LinearLayout02 toRightOf imageView. You will relief the onMeasure of the ViewGroup a lot.
Tip2
It seems like when the text changes height the whole view need to be reinflated.A common technic to avoid that it to make list Item fixed in height. So the listview can reuse the recycled views without reinflating.
Tip3
Give your LinearLayout02 a fixed height of 64dp or Fill_Parent since you don't have any left space, but the Layout don't know that and try to rearrange it self every time since the text is also Wrap_content.
Also you said that if you remove the ImageView everything is fast again.If the above don't have any effect can you please try this? Since you know that imageView size is fixed.
Extend your imageView and override requestLayout() method.
publicclassMyImageViewextendsImageView {
publicPImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
publicPImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
publicPImageView(Context context) {
super(context);
}
@OverridepublicvoidrequestLayout() {
/*
* Do nothing here
*/
}
}
Now include the MyImageView widget to your XML like that.
<com.package_name.MyImageView
android:id="@+id/ImageView01"
android:layout_width="40dip"
android:layout_height="40dip"
android:src="@drawable/arrow_up_green"
android:background="@android:color/transparent">
</com.package_name.MyImageView >
Solution 2:
After optimizing my getView() method to use a holder and to reuse convertView if it's not null, my listview was still pretty laggy. Then, I've tried
listView.setScrollingCacheEnabled(false);
and it solved it at once.
Hope this helps someone.
Solution 3:
I just discovered this and I wanna share it with you guys.
I tried ALL the solutions provided but nothing worked. What was causing the problem is the length of the text I am feeding one of my TextView views because i'm using
mTextView.SetText(theLongString)
in my adapter in my getView method. Now that I shrinked my String, the listview is VERY smooth :)
Solution 4:
It took a while! I tried everything. Disabling the scroll cache, viewHolder, cacheColorHint ... but nothing worked!
After searching many hours I found the root of all evil!
In my themes.xml I had a scaling background image:
<item name="android:windowBackground">@drawable/window_bg</item>
After removing the beackground everything was butter smooth.
I hope this helps someone!
Solution 5:
To improve performance of listview use both or any one of the two - (Simple implementation)
- ViewHolder
- AsyncTask (a separate thread)
If you have moderately long lists I recommend ViewHolder otherwise for large lists (like in the case of a music player) I recommend using ViewHolder along with AsyncTask. The key to smooth ListView scrolling is to reduce memory consumption as much as possible.
To implement ViewHolder, is simple. Just create a static class in your custom Adapter that holds all the views that you find via findViewById. So this is how it should look -
static class ViewHolder
{
TextView text;
TextView timestamp;
ImageView icon;
ProgressBar progress;
int position;
}
Then, the next time you need to findViewById any of these views, just reference the ViewHolder like this-
ViewHolder holder = new ViewHolder();
holder.icon = (ImageView) yourView.findViewById(R.id.listitem_image);
holder.text = (TextView) yourView.findViewById(R.id.listitem_text);
holder.timestamp = (TextView) yourView.findViewById(R.id.listitem_timestamp);
holder.progress = (ProgressBar) yourView.findViewById(R.id.progress_spinner);
This is tested code and taken from one of my projects. However, the original source is here - http://developer.android.com/training/improving-layouts/smooth-scrolling.html
The lists become smoother using ViewHolder. Using AsyncTask is a little more complex, but do check out the link if you wish to implement the AsyncTask along with ViewHolder for a much smoother scrolling experience. Good Luck!
Post a Comment for "Listview Very Slow When Scrolling (using Viewholder/recycling)"