I've followed this, this and this to make my ListView have the best performance possible. Actually, following the third link I substancially improved the smoothness of scrolling.
The thing is that I'm using a customized layout for each row which contains 2 ImageViews (one of them unchanging, and the second one with two possible assignations of drawables), and two TextViews, so this is the definition:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/elem_list"
android:orientation="horizontal">
<ImageView
android:id="@+id/chanlist_featured"
android:layout_width="20dp"
android:layout_height="30dp"
android:layout_marginTop="8dp"
android:contentDescription="@string/desc_gen_image"
android:gravity="center" />
<TextView
android:id="@+id/chanlist_chan"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:layout_weight="13"
android:ellipsize="marquee"
android:maxLines="2"
android:padding="10dp" />
<LinearLayout
android:layout_width="40dp"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/chanlist_usercount"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingTop="10dp"
android:ellipsize="marquee"
android:gravity="center"
android:maxLines="2"
android:textSize="11sp" />
<ImageView
android:layout_width="10dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingTop="8dp"
android:contentDescription="@string/desc_gen_image"
android:background="@drawable/user" />
</LinearLayout>
</LinearLayout>
Ok, no problem up to now. So I defined my customized ArrayAdapter whose getView() method is the following:
// This is the public class for the ViewHolder object
public static class vhItem {
TextView maintext;
ImageView mainimage;
TextView users;
}
@Override
public View getView(final int position, View convertView, final ViewGroup parent) {
vhItem viewHolder;
if (convertView == null) {
final LayoutInflater inflater = ((Activity) context).getLayoutInflater();
convertView = inflater.inflate(resourceId, parent, false);
viewHolder = new vhItem();
viewHolder.maintext = (TextView) convertView.findViewById(R.id.chanlist_chan);
viewHolder.mainimage = (ImageView) convertView.findViewById(R.id.chanlist_featured);
viewHolder.users = (TextView) convertView.findViewById(R.id.chanlist_usercount);
convertView.setTag(viewHolder);
}
else
viewHolder = (vhItem) convertView.getTag();
final InfoCanal chaninfo = (InfoCanal) getItem(position);
viewHolder.maintext.setText(chaninfo.getChanName() + "\n" + chaninfo.getTopic());
viewHolder.users.setText(String.valueOf(chaninfo.getUserCount()));
/* star and star_off are the two Drawable objects that I initialized in the constructor of
the class, so I don't have to findViewById() them each time I call this method */
if (chaninfo.getFeatured())
viewHolder.mainimage.setImageDrawable(star);
else
viewHolder.mainimage.setImageDrawable(star_off);
return convertView;
}
And here comes the problem: I'm trying to show around 300 list elements. As I said, the list scrolls smoothly (and most of the posts I found about improving performance of ListViews talk just about this), but the time between the initialization call of the adapter (new MyOwnArrayAdapter() ...) and the visualization of the list is enormous (about 15-20 seconds). I can simply embellish it showing a progress bar, but I wonder if I'm doing something inefficient here as I think 300 elements are not as much.
Any advice appreciated!
---------- EDIT ----------
I'm including the constructor:
public class StableArrayAdapter<T> extends ArrayAdapter<T> {
final private Context context;
final private int resourceId;
final private List<T> objects;
final Drawable star, star_off;
// There I store the objects to include in the list
final private HashMap<T, Integer> mIdMap = new HashMap<T, Integer>();
// I had to Override some methods related to the observers, that's why I store this
final private ArrayList<DataSetObserver> observers = new ArrayList<DataSetObserver>();
// Constructor
public StableArrayAdapter(final Context context_, final int resourceId_, final List<T> objects_) {
super(context_, resourceId_, objects_);
this.context = context_;
this.resourceId = resourceId_;
this.objects = objects_;
for (int i = 0; i < objects.size(); i++)
mIdMap.put(objects.get(i), i);
star = context.getResources().getDrawable(R.drawable.checkbox_star);
star_off = context.getResources().getDrawable(R.drawable.checkbox_star_down);
}
...
}