【问题标题】:How to improve performance on Android ListView如何提高 Android ListView 的性能
【发布时间】:2014-03-27 02:05:23
【问题描述】:

我的 ListView 加载速度很慢。我的应用中有多个选项卡,每次切换到 ListView 选项卡都需要很长时间(~1-1.5 秒)。

我的getView()来自适配器的方法:

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    final ViewHolder holder;
    if (convertView == null) {
        convertView = LayoutInflater.from(ctx).inflate(R.layout.gallery_list_item, parent, false);
        holder = new ViewHolder();
        holder.image = (ImageView) convertView.findViewById(R.id.image);
        holder.text = (TextView) convertView.findViewById(R.id.text);
        holder.date = (TextView) convertView.findViewById(R.id.date);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    bindItems(position, holder);
    ImageLoader.getInstance().displayImage(Uri.fromFile(new File(documents.get(position).getPath())).toString(), holder.image, options, animateFirstListener);
    return convertView;
}

@Background
void bindItems(final int position, final ViewHolder holder) {
    holder.date.setTypeface(MainApplication.OpenSans(ctx));
    holder.text.setTypeface(MainApplication.OpenSansBold(ctx));

    SimpleDateFormat date = new SimpleDateFormat("dd.MM.yyyy");
    SimpleDateFormat time = new SimpleDateFormat("hh:mm:ss");
    holder.date.setText(date.format(documents.get(position).getCreateDate()) + "  " + time.format(documents.get(position).getCreateDate()));

    holder.text.setText(documents.get(position).getDocument());
}

我的gallery_list_layout.xml 的一部分(除了列表显示一些与我的问题无关的按钮和微调器):

 <ListView
    android:id="@+id/mylist"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
</ListView>

还有我的gallery_list_item.xml(对于一个列表项):

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/gallery_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:descendantFocusability="blocksDescendants" >

<ImageView
    android:id="@+id/image"
    android:layout_width="@dimen/image_width"
    android:layout_height="@dimen/image_height"
    android:layout_centerVertical="true"
    android:contentDescription="@string/app_name"
    android:scaleType="centerCrop" />

<LinearLayout
    android:id="@+id/list"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_toRightOf="@id/image"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/date"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>

<CheckBox
    android:id="@+id/chkbox"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_centerVertical="true" />
</RelativeLayout>

我省略了一些样式属性以使其更具可读性。

到目前为止我做了什么:

  • 使用通用图像加载器,但问题不在于图像加载(性能大致相同)
  • 使用match_parenton layout_heightlayout_width 仅加载必要的数据(这大大提高了我的性能,但仍然不够)
  • 避免在我的 Adapter getView() 方法中进行任何数据库查询
  • 在后台任务中绑定数据

有人看到我犯的错误吗?我可能做错了什么?

【问题讨论】:

  • 那是什么类型的适配器?数组还是光标?
  • 数组;我的适配器扩展了BaseAdapter
  • 这可能就是原因。你的数据有多大?有多少文件?
  • 初始加载只有6个项目(设备上的空间),甚至需要很长时间。在我的列表中大约有 30-50 项。如何将其更改为光标?
  • 你可能想在后台执行一些工作,你可以查看我的相关帖子,我在ListView 中描述了我如何解决性能问题,我在其中加载了一些相当大的图像stackoverflow.com/questions/19469073/…

标签: android performance listview android-fragments android-listview


【解决方案1】:

首先子类化 TextView 并在构造函数中设置字体。不需要每次新项目进来时都设置字体。您还可以缓存 DateFormatters 和 LayoutInflater。内存分配很慢。

如果你有 RelativeLayout 用于定位,为什么要嵌套 LinearLayout ?有点奇怪

【讨论】:

  • 感谢 TextView 的提示。我做到了,但不幸的是字体不是问题。 LinearLayout 仍然存在,因为我还没有时间修复它。我知道这有点奇怪,但应该不会造成任何问题,对吧?
  • 不应该,尝试缓存格式化程序。您可以尝试测量后续方法调用的时间 - 这将为您提供线索什么是问题。您可以检查(通过注释掉)ImageLoader 的行是否没有问题
  • 我的问题现在已经解决了。主要原因是对 init 方法的不必要调用,但您的修复帮助我改进了列表
【解决方案2】:

在 if(view==null) 语句的 getview 方法中放置 setTypeface

【讨论】:

  • 真的。创建字体可能很繁重。
  • 当我重新加载我的列表时,只创建了前 6 个项目(因此 setTypeface 像以前一样经常被调用)。因此,将 setTypeface 放在 view==null 中当然是一个很好的提示,谢谢 btw!,但它对性能没有帮助
  • 您将 setTypeface 放在 bind 方法中,它会为 listview 的所有项目运行,而不仅仅是 6 个 itrms
  • 我将更改 setTypeface,但它不会减慢应用程序的速度(为了测试,我刚刚删除了它,它需要和以前一样多的时间)
  • 可能会导致ImageLoader
【解决方案3】:

这个MainApplication.OpenSans(ctx) 可能会创建一个完整的字体实例。这可能是一个相当漫长的操作。

我建议您在应用启动时创建一次,然后再使用该引用。 (其他字体也一样,不用说)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-24
    • 2012-12-16
    • 2018-10-14
    • 1970-01-01
    相关资源
    最近更新 更多