Android 提高ListView分配的性能
我已经遵循了,并使我的ListView具有尽可能最好的性能。实际上,在第三个链接之后,我实质上提高了滚动的平滑度 问题是,我正在为每一行使用一个自定义布局,其中包含2个ImageView,其中一个不变,第二个具有两个可能的可绘制内容分配,以及两个TextView,因此这是定义:Android 提高ListView分配的性能,android,performance,android-listview,android-adapter,Android,Performance,Android Listview,Android Adapter,我已经遵循了,并使我的ListView具有尽可能最好的性能。实际上,在第三个链接之后,我实质上提高了滚动的平滑度 问题是,我正在为每一行使用一个自定义布局,其中包含2个ImageView,其中一个不变,第二个具有两个可能的可绘制内容分配,以及两个TextView,因此这是定义: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/re
<?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>
问题来了:我试图显示大约300个列表元素。正如我所说,列表滚动顺畅,我发现的大多数关于提高ListView性能的帖子都在谈论这一点,但是适配器new MyowArrayAdapter的初始化调用之间的时间。。。列表的可视化效果非常巨大,大约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);
}
...
}
只是漫游-使用某种idex?将列表转换为HashMap,而不是在getView中执行getItemposition搜索HashMap中的值!!!==位置为什么不保留原始列表并从中获取正确的数据元素?我猜问题在于构造函数中的列表循环。我想知道是否有些列表实现每次都会遍历其底层数据集以满足size方法。那缓存呢
int size = objects.size();
for (int i = 0; i < size; i++) {
mIdMap.put(objects.get(i), i);
}
或者可以使用迭代器最终我得到了它。基本上,它与初始化或getView方法无关。在处理StableArrayAdapter构造函数的过程中,我可以并行地做一些额外的事情,我在调用新的StableArrayAdapter之前启动了一个线程,为了同步该线程的结果和初始化,我忘了我已经声明了倒计时锁存器,因此,适配器初始化下面的代码基本上是在等待线程调用倒计时方法 我很抱歉,伙计们,同时谢谢你们,从最初帖子中的代码来看,没有人会知道这一点,我无意中提到了这一部分,认为这并不重要
同时,我希望这可以帮助一些人,或者至少提供一些线索。如果滚动不是问题,那么您的问题不在getView中。它在适配器初始化中。如何获取填充ListView的数据?将此代码添加到您的帖子中。传递到StableArrayAdapter的数据是通过解析一个URL获得的,该URL具有这300个项目的定义。我不计算这需要多少时间,因为这是后台线程中的一个单独任务,顺便说一句。一旦我得到了这些项,我就将它们传递给我在帖子中编辑的构造函数。正如您可能看到的,StableArlayAdapter类被参数化了T,这是因为我想将它用于具有相同逻辑但不同数据类型的多个活动,并避免为每个扩展定义ArrayAdapter的一个扩展。我使用HashMap是因为它非常有效,但对于一些活动,特别是不是这个活动,我需要有稳定的id,即即使在更新HashSet之后元素也必须有相同的id。在您的注释的基础上,我在循环之前和之后放了一个日志对象,耗时0.12秒。我想这不是问题所在。然而,这似乎很奇怪,因为列表的内容在离开构造函数几秒钟后出现。。。
int size = objects.size();
for (int i = 0; i < size; i++) {
mIdMap.put(objects.get(i), i);
}