应用程序在使用android:layerType="software"时出现卡顿问题。

3
我正在制作一个非常简单的应用程序(基本上是一个只有几张图片的ListView)。在我的测试设备上(一台带有原生Android系统的摩托罗拉Moto G)上表现良好。
然而,我想让我的ListView有点状分隔符。因此,我创建了一个list_divider.xml文件来定义分隔符,并将其设置为ListView中要使用的分隔符。我已经在我的Moto G上尝试过了,但它没有显示出虚线。
所以我在谷歌上搜索并发现了这里解决方案。禁用视图的硬件加速解决了错误并正确显示了分隔符。
然而,现在我又遇到了另一个问题:由于禁用了硬件加速,当滚动时应用程序开始变得卡顿。
是否有一种方法可以拥有虚线分隔符而不禁用硬件加速或者至少使性能与禁用之前相当?
编辑:以下是我使用的适配器代码:
public class AstronautArrayAdapter extends ArrayAdapter<Astronaut> {

    public static final String TAG = "AstronautArrayAdapter";

    public AstronautArrayAdapter(Context context, List<Astronaut> objects) {
        super(context, R.layout.astronauts_list_row, objects);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        RowViewHolder holder = null;
        if (convertView == null) {
            LayoutInflater inflater = ((Activity) getContext()).getLayoutInflater();
            convertView = inflater.inflate(R.layout.astronauts_list_row, parent, false);

            holder = new RowViewHolder();
                holder.name = (TextView) convertView.findViewById(R.id.nameOfAustronaut);
            holder.daysInSpace = (TextView) convertView.findViewById(R.id.numberOfDaysInSpace);
            holder.country = (ImageView) convertView.findViewById(R.id.countryImage);
            holder.title = (TextView) convertView.findViewById(R.id.titleOfAstronaut);

            convertView.setTag(holder);
        } else {
            holder = (RowViewHolder) convertView.getTag();
        }

        Astronaut astronaut = getItem(position);

        holder.name.setText(astronaut.getName());
        holder.daysInSpace.setText(Integer.toString(astronaut.getDaysInSpace()));
        holder.country.setImageBitmap(astronaut.getCountryImage(getContext()));
        holder.title.setText(astronaut.getTitle());

        return convertView;
    }

    private static class RowViewHolder {
        TextView name;
        TextView daysInSpace;
        ImageView country;
        TextView title;
    }

}

编辑2:以下是两个相关的布局文件:
activity_main.xml
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/astronautsList"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" 
    android:padding="16dp"
    android:dividerHeight="3dp"
    android:divider="@drawable/list_divider"
    android:layerType="software" />

list_divider.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="line" >

    <stroke
        android:width="1px"
        android:color="@android:color/black"
        android:dashWidth="5px"
        android:dashGap="1px" />

    <size android:height="3dp" />

</shape>

1
那一行代码:holder.country.setImageBitmap(astronaut.getCountryImage(getContext())); 看起来你可能正在UI线程上进行Bitmap解码(甚至下载)。你是这样做的吗? - Budius
不,在应用程序开始时,我会下载所有需要的内容并将其保存在本地。(应用程序在启动时确实会有一些延迟,但我知道这是由于下载所致,并且这是有意为之的。) - brgr
“将其本地保存”仍意味着在该行调用期间,位图将从磁盘读取(I/O操作),并进行解码(CPU密集型操作)。我会在答案中写出我的建议。 - Budius
2个回答

1
你看到的延迟可能的解决方案是:
将此行添加到build.gradle文件的dependencies部分
compile 'com.squareup.picasso:picasso:2.3.2'

并替换这一行

holder.country.setImageBitmap(astronaut.getCountryImage(getContext()));

使用

Picasso.with(context).load(/* insert the URL here */).into(holder.country);

并且删除下载所有图像并本地保存的代码。Picasso会自动下载/解码位图,并为您管理磁盘和RAM缓存。

ps.:

如果您没有使用Gradle:

  1. 您应该转换为Android-Studio并使用Gradle
  2. 忘记我说的在gradle文件中添加行的内容,只需从网站下载jar文件,放入libs文件夹,并确保在项目设置中混淆jar文件以确保它包含在您的APK中(因为我很久以前就放弃了Eclipse,所以我真的不记得这些设置是如何工作的)

回复 #2:将它放在“libs”中,ADT会为您完成,幸运的是Google并没有完全放弃ADT。 - TWiStErRob

0

由于您没有提到它,您是否已经实现了ViewHolder模式?

由于ListView会回收视图,因此必须膨胀布局并插入任何文本和图像。您通常在此代码部分中调用findViewById,这相当昂贵。 ViewHolder模式解决了这个问题,并且很容易实现。

请参阅Google的一个很棒的教程。

http://developer.android.com/training/improving-layouts/smooth-scrolling.html


1
是的,我确实使用了ViewHolder,但仍然存在卡顿问题。 - brgr
将内部类设置为静态。 - Graham Smith
你不需要私有的,但除此之外代码看起来很好,可能需要布局文件来确定。 - Graham Smith
我会添加它,稍等片刻 ;) - brgr
由于我在它的网站上找不到任何信息,你认为即使关闭硬件加速(因为我需要点线时),它的表现也会很好吗?因为我的应用程序已经在使用硬件加速时表现良好。 - brgr
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接