【发布时间】:2014-01-07 21:23:57
【问题描述】:
我已关注this、this 和this,以使我的 ListView 具有尽可能好的性能。实际上,在第三个链接之后,我大大提高了滚动的流畅度。
问题是我为每一行使用自定义布局,其中包含 2 个 ImageView(其中一个不变,第二个具有两个可能的可绘制对象分配)和两个 TextView,所以这是定义:
<?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>
好的,到目前为止没问题。所以我定义了我自定义的 ArrayAdapter,它的 getView() 方法如下:
// 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;
}
问题来了:我试图显示大约 300 个列表元素。正如我所说,列表滚动顺畅(我发现的大多数关于提高 ListViews 性能的帖子都在谈论这一点),但是适配器的初始化调用(new MyOwnArrayAdapter() ...)和可视化之间的时间列表很大(大约 15-20 秒)。我可以简单地修饰它显示一个进度条,但我想知道我是否在这里做一些低效的事情,因为我认为 300 个元素并没有那么多。
任何建议表示赞赏!
--------- 编辑 ----------
我包括构造函数:
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);
}
...
}
【问题讨论】:
-
如果滚动不是问题,那么您的问题不在
getView()。它在您的适配器初始化中。您如何获取填充 ListView 的数据?将此代码添加到您的帖子中。 -
传递给 StableArrayAdapter() 的数据被解析为具有这 300 项定义的 URL。我没有计算这花费的时间,因为它是一个单独的任务(在后台线程中,顺便说一句)。获得这些项目后,我将它们传递给我在帖子中编辑的构造函数。
标签: android performance android-listview android-adapter