如何提高Android ListView的性能

时间:2014-03-26 17:47:18

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

我的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>

我遗漏了一些样式属性,使其更具可读性。

到目前为止我做了什么:

  • 使用Universal Image Loader,但问题不在于图像加载(性能大致相同)
  • match_parentlayout_height上使用layout_width仅加载必要的数据(这可以提高我的表现很多,但仍然不够)
  • 避免我的适配器getView()方法
  • 中的任何数据库查询
  • 在后台任务中绑定数据

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

3 个答案:

答案 0 :(得分:0)

首先将TextView子类化,并在构造函数中设置字体。每次有新项目进入时都没有必要设置字体。您还可以缓存DateFormatters和LayoutInflater。内存分配非常慢。

如果您使用RelativeLayout进行定位,为什么要嵌套LinearLayout?这有点奇怪

答案 1 :(得分:0)

将setTypeface放在getview方法的if(view == null)

语句中

答案 2 :(得分:0)

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

我建议您在应用启动时创建一次,并在之后使用该引用。 (同样适用于其他字体,不言而喻)