Search code examples
androidandroid-listviewscrollandroid-custom-viewandroid-adapter

Android - Custom Listview Scrolling is Very Slow


I've got a listview which sometimes inflate a XML (TextView Item) or another XML (TextView+Image Item). And i followed these instructions to get a better performance.

http://www.google.com/events/io/2010/sessions/world-of-listview-android.html

https://dl.google.com/googleio/2010/android-world-of-listview-android.pdf

http://android.amberfog.com/?p=296

It's now better, but still can't get best performance and still scroll is working slowly. Here's my code :

GetView : (//ViewHolder 0 -> Section Item ViewHolder 1 -> Entry Item)

@Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View v = convertView;
        ViewHolder[] viewHolders=new ViewHolder[2];
        final ListItems.Item i = items.get(position);
        if (i != null) {
            if(i.isSection()){
                TextView sectionView;
                ListItems.SectionItem si = (ListItems.SectionItem)i;
                if (v==null || ((ViewHolder[])v.getTag())==null || ((ViewHolder[])v.getTag())[0]==null)
                {
                    v = vi.inflate(R.layout.order_list_item_section, null);
                    sectionView= (TextView) v.findViewById(R.id.list_item_section_text);
                    viewHolders[0]=new ViewHolder();
                    viewHolders[0].Title=sectionView;
                    v.setTag(viewHolders);
                }
                else
                {
                    viewHolders[0]=((ViewHolder[]) v.getTag())[0];
                    sectionView=viewHolders[0].Title;
                }
                sectionView.setBackgroundColor(android.graphics.Color.BLACK);
                sectionView.setText(si.getTitle());
            }
            else if(i.isEntryItem())
            {               
                ListItems.EntryItem ei = (ListItems.EntryItem)i;
                TextView title = null,subtitle = null;
                ImageView img = null;
                if (v==null || ((ViewHolder[])v.getTag())==null || ((ViewHolder[])v.getTag())[1]==null)
                {
                    v = vi.inflate(R.layout.order_list_item_entry, null);
                    title = (TextView)v.findViewById(R.id.list_item_entry_title);
                    img=(ImageView)v.findViewById(R.id.list_item_entry_drawable);
                    subtitle = (TextView)v.findViewById(R.id.list_item_entry_summary);
                    viewHolders[1]=new ViewHolder();
                    viewHolders[1].Title=title;
                    viewHolders[1].SubTitle=subtitle;
                    viewHolders[1].TableImage=img;
                    v.setTag(viewHolders);
                }
                else
                {
                    viewHolders[1]=((ViewHolder[]) v.getTag())[1];
                    title=viewHolders[1].Title;
                    subtitle=viewHolders[1].SubTitle;
                    img=viewHolders[1].TableImage;
                }
                title.setTextSize(20);
                title.setTextColor(android.graphics.Color.BLACK);
                title.setText(Html.fromHtml("<b><i>"+ei.title+"</b></i>"));
                img.setImageBitmap(ei.tableImage);  
                img.setScaleType(ScaleType.FIT_XY);
                img.setAdjustViewBounds(true);
                if(!ei.subtitle.equals(""))
                {
                    subtitle.setTextSize(15);
                    subtitle.setTextColor(android.graphics.Color.GRAY);
                    subtitle.setText(Html.fromHtml("<i>"+ei.subtitle+"</i>"));
                }
            }

ViewHolder : 

    static class ViewHolder {
          TextView Title;
          TextView SubTitle;
          ImageView TableImage;
         }

EDIT :

order_list_item_section.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <include
        android:id="@+id/list_item_section_text"
        layout="@android:layout/preference_category" />

</LinearLayout>

order_list_item_entry.xml :

<?xml version="1.0" encoding="utf-8"?>

  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:minHeight="?android:attr/listPreferredItemHeight"
    android:gravity="center_vertical"
    android:paddingRight="?android:attr/scrollbarSize"
    android:background="#ffffff">

    <ImageView
        android:id="@+id/list_item_entry_drawable"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingLeft="6dp"/>

    <RelativeLayout
        android:layout_width="0dip"
        android:layout_height="wrap_content"
        android:layout_marginLeft="0dip"
        android:layout_marginRight="6dip"
        android:layout_marginTop="6dip"
        android:layout_marginBottom="6dip"
        android:layout_weight="1">

        <TextView android:id="@+id/list_item_entry_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:singleLine="true"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:ellipsize="marquee"
            android:fadingEdge="horizontal" />

        <TextView android:id="@+id/list_item_entry_summary"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/list_item_entry_title"
            android:layout_alignLeft="@id/list_item_entry_title"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:singleLine="true"
            android:textColor="?android:attr/textColorSecondary" /> 

    </RelativeLayout>

</LinearLayout>

I need any suggestions. Thanks.


Solution

  • If this is accepted I think I need to include the debug here:

    1. Remove the ellipsize and fadingedge, and for both TextView set the width to match_parent, if scrolling still slow, try next.

    2. scaleType="fitXY" together with wrap_content on ImageView actually sounds quite, conflicting if you ask me, try specifically setting the width and height to maybe 48dp or 55dp, then fitXY makes sense.

    Here's an example of functions to a proper BaseAdapter class:

    public static final int SECTION = 2;
    public static final int ENTRY_ITEM = 1;
    private List<ListItems.Item> items; // I believe you have this List declared?
    
    public YourClassConstructor(){
        //Whatever you need to accept and assign, probably the list itself.
    }
    
    public int getCount() {
        return items.size();
    }
    
    public Object getItem(int position) {
        return items.get(position);
    }
    
    public long getItemId(int position) {
        return (long) position; // Or anything that can define your item
    }
    
    @Override
    public int getViewTypeCount() {
        return 2; // 2 because you have Section and EntryItem
    }
    
    @Override
    public int getItemViewType(int position) {
        int itemViewType;
        ListItems.Item i = items.get(position);
    
        if(i.isSection()){
            itemViewType = SECTION;
        }else{
            itemViewType = ENTRY_ITEM;
        }
    
        return itemViewType;
    }
    
    @Override
    public View getView(final int position, final View convertView, final ViewGroup parent {
        //Here your convertView will always be the one you need, either as a section or entry_item
        //Unless there is no convertView available yet.
        //So your (ViewHolder[])v.getTag())[0/1] will less likely be null.
    }