通过滚动的ListView有些图像非常laggy图像、ListView、laggy

2023-09-06 15:43:21 作者:风流又倜傥

我有下面的画面,它包含了一些图像(6%可见页)。上下滚动似乎很laggy给我。这就像它的再次渲染图像。滚动备份似乎比向下滚动差。

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

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

 私有类HistoryViewBinder实现SimpleCursorAdapter.ViewBinder
{
    //私人诠释wallpaperNumberIndex;
    私人诠释timeIndex;
    私人诠释categoryIndex;
    私人诠释imageIndex指定;

    私人java.text.DateFormat中的日期格式;
    私人java.text.DateFormat中TIMEFORMAT;
    私人日期D =新的日期();

    公共HistoryViewBinder(上下文的背景下,光标光标)
    {
        DATEFORMAT = android.text.format.DateFormat.getDateFormat(上下文);
        TIMEFORMAT = android.text.format.DateFormat.getTimeFormat(上下文);

        // 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);
    }

    @覆盖
    公共布尔setViewValue(查看视图,光标指针,整数参数:columnIndex)
    {
        Log.d(TAG,setViewValue);

        如果(查看的instanceof的TextView)
        {
            Log.d(TAG的TextView);
            TextView的电视=(TextView的)观点;

            如果(参数:columnIndex == timeIndex)
            {
                Log.d(TAG,timeIndex);
                d.setTime(cursor.getLong(参数:columnIndex));
                tv.setText(timeFormat.format(D)++ dateFormat.format(D));
                返回true;
            }
            否则,如果(参数:columnIndex == categoryIndex)
            {
                Log.d(TAG,categoryIndex);
                tv.setText(cursor.getString(参数:columnIndex));
                返回true;
            }
        }
        否则,如果(查看的instanceof ImageView的)
        {
            Log.d(TAG,ImageView的);
            ImageView的IV =(ImageView的)观点;

            如果(参数:columnIndex == imageIndex指定)
            {
                Log.d(TAG,imageIndex指定);
                byte []的图像= cursor.getBlob(参数:columnIndex);
                位图的BitmapImage = BitmapFactory.de codeByteArray(图像,0,image.length);
                iv.setImageBitmap(BitmapImage的);
                返回true;
            }
        }

        返回false;
    }
}
 

解决方案

问题是,每个图像是德codeD此刻的看法是ppared用于显示$ P $。 ListView控件将回收您的意见,这意味着,在目前的视图离开屏幕会被重用,因此图像将被覆盖,垃圾收集。如果该项目重新进入屏幕上的图像具有同样为与数据库德$ C $光盘。

解码是合理的速度快,但如果用户非常快速地改变在列表中的位置,所有的解码调用会让你的列表非常laggy。

我会implment类似的ImageCache。一类是持有地图与在WeakReferences 以图像。每次你想让你​​看看如果图像媒体链接的地图,如果WeakReference的仍指向一个对象,以显示图像,如果这不是你需要去code中的图像,然后将其保存的情况下地图。

看看延迟加载的问题,这些都将告诉你如何把一个后台任务解码,然后更新列表中的图像加载的时刻。这是一个有点付出更多的努力,但它可以使列表得多快多了。如果你要使用code例如从延迟加载问题,尝试使用 AsyncTasks 而不是线程完成解码

I've got the below screen that contains some images (6 per visible page). Scrolling up and down seems quite laggy to me. It's like it's rendering the images again. Scrolling back up seems worse than scrolling down.

ListView控件中显示的图片存放在哪里

Anyone know how to increase performance in such an area to create a nice smooth scroll?

Update: The images and text is all retrieved from my SQLite database. The list is created using SimpleCursorAdapter.

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;
    }
}

解决方案

The problem is that each image is decoded at the moment the view is prepared for showing. The ListView will recycle your views that means that at the moment a view leaves the screen it will be reused and therefore the image will be overwritten and garbage collected. If the item reenters the screen the image has to be decoded from the database again.

The decoding is reasonable fast but if the user changes the position in the list very quickly all the decoding calls will make your list very laggy.

I would implment something like an ImageCache. A class that holds a Map with WeakReferences to images. Everytime you want to display an image you take a look if the image is allready in the map and if the WeakReference still points to an object, if this is not the case you need to decode the image and then store it in the map.

Take a look at the lazy loading questions, these will show you how to put the decoding in a background task and then update the list the moment the images are loaded. It is a bit more effort but it can make the list much much more faster. If you are going to use the code example from the lazy loading questions try to use AsyncTasks instead of Threads to do the decoding in.