滚动浏览ListView时,一些图像非常滞后

时间:2010-09-06 12:21:41

标签: android performance android-listview

我的下面的屏幕包含一些图像(每个可见页面6个)。向上和向下滚动对我来说似乎很迟钝。就像它再次渲染图像一样。向上滚动似乎比向下滚动更糟糕。

任何人都知道如何提高这样一个区域的性能,以创建一个漂亮的平滑滚动?

更新:图像和文本都是从我的SQLite数据库中检索出来的。该列表是使用SimpleCursorAdapter创建的。

Gallery

private class HistoryViewBinder implements SimpleCursorAdapter.ViewBinder 
{
    //private int wallpaperNumberIndex;
    private int timeIndex;
    private int categoryIndex;
    private int imageIndex;

    private java.text.DateFormat dateFormat;
    private java.text.DateFormat timeFormat;
    private Date d = new Date();

    public HistoryViewBinder(Context context, Cursor cursor) 
    {
        dateFormat = android.text.format.DateFormat.getDateFormat(context);
        timeFormat = android.text.format.DateFormat.getTimeFormat(context);

        //wallpaperNumberIndex = cursor.getColumnIndexOrThrow(HistoryDatabase.KEY_WALLPAPER_NUMBER);
        timeIndex = cursor.getColumnIndexOrThrow(HistoryDatabase.KEY_TIME);
        categoryIndex = cursor.getColumnIndexOrThrow(HistoryDatabase.KEY_CATEGORY);
        imageIndex = cursor.getColumnIndexOrThrow(HistoryDatabase.KEY_IMAGE);
    }

    @Override
    public boolean setViewValue(View view, Cursor cursor, int columnIndex) 
    {
        Log.d(TAG, "setViewValue");

        if (view instanceof TextView)
        {
            Log.d(TAG, "TextView");
            TextView tv = (TextView) view;

            if (columnIndex == timeIndex)
            {
                Log.d(TAG, "timeIndex");
                d.setTime(cursor.getLong(columnIndex));
                tv.setText(timeFormat.format(d) + "  " + dateFormat.format(d));
                return true;
            }
            else if (columnIndex == categoryIndex)
            {
                Log.d(TAG, "categoryIndex");
                tv.setText(cursor.getString(columnIndex));
                return true;
            }
        }
        else if (view instanceof ImageView)
        {
            Log.d(TAG, "ImageView");
            ImageView iv = (ImageView) view;

            if (columnIndex == imageIndex)
            {
                Log.d(TAG, "imageIndex");
                byte[] image = cursor.getBlob(columnIndex);
                Bitmap bitmapImage = BitmapFactory.decodeByteArray(image, 0, image.length);
                iv.setImageBitmap(bitmapImage);
                return true;
            }
        }

        return false;
    }
}

3 个答案:

答案 0 :(得分:6)

问题是每个图像在视图准备好显示时被解码。 ListView将回收您的视图,这意味着当视图离开屏幕时它将被重用,因此图像将被覆盖并被垃圾收集。如果项目重新进入屏幕,则必须再次从数据库中解码图像。

解码速度合理,但如果用户非常快速地更改列表中的位置,则所有解码调用都会使您的列表非常滞后。

我会像ImageCache这样的东西。一个包含WeakReferences到图像的地图的类。每当您想要显示图像时,您可以查看图像是否已经在地图中,并且如果WeakReference仍然指向对象,如果不是这种情况,则需要解码图像然后将其存储在地图中。

看一下延迟加载问题,这些问题将向您展示如何将解码放在后台任务中,然后在加载图像时更新列表。这需要更多的努力,但它可以使列表更快。如果您要使用延迟加载问题中的代码示例,请尝试使用AsyncTasks而不是Threads来进行解码。

答案 1 :(得分:1)

这是......你应该阅读的内容,它应该可以帮助你解决问题(整个显示位图有效地部分): http://developer.android.com/training/displaying-bitmaps/process-bitmap.html

答案 2 :(得分:0)

如果您的图像尺寸不合适,它们会在运行中进行缩放,这不是一个便宜的操作,特别是对于大图像。确保从数据库中加载缩略图,而不是壁纸。

此外,您可以使用Traceview找出您的时间花在哪里。