从数据库中的位图平滑滚动GridView

时间:2014-12-25 18:41:47

标签: android gridview bitmap

我在数据库中有一些图像,我想在GridView中显示它们。

这是我从数据库中获取Bitmaps的函数

public Bitmap getBitmaps(String tableName, int id, int index) {
        String selectQuery = "SELECT  * FROM " + tableName + " WHERE "
                + BaseColumns._ID + " = " + id;
        Cursor cursor = mDatabase.rawQuery(selectQuery, null);
        cursor.moveToFirst();
        byte[] byteArray = cursor.getBlob(index);

        return BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
    }

这是我的GridView适配器

public View getView(final int position, View convertView,
                ViewGroup parent) {
            final ViewHolder viewHolder;
            if (convertView == null) {
                //..
            } else {

            //..
            }

            new AsyncTask<ViewHolder, Void, Bitmap>() {
                private ViewHolder v;

                @Override
                protected Bitmap doInBackground(ViewHolder... params) {
                    v = params[0];    

                    return getBitmaps(tableName, id,index);
                }

                @Override
                protected void onPostExecute(Bitmap result) {

                    super.onPostExecute(result);

                    if (v.position == position) {
                        v.image.setImageBitmap(result);
                    }
                }
            }.execute(viewHolder);
            return convertView;
        }

现在我遇到了一个问题:

例如,我的GridView中有超过20个项目。当我向下滚动到列表的末尾时,需要1或2秒(如果列表变大则需要更多秒)来加载某个位置的图像。如果我滚动到列表顶部,则会出现同样的问题。

现在我如何优化我的代码以平滑而快速地滚动?

1 个答案:

答案 0 :(得分:1)

您必须更改方法,例如创建一个ImageLoader类并将请求传递给它。在ImageLoader中创建一个内存缓存LRUCache然后,如果请求在缓存中,则只返回它,如果它没有从DB加载,然后将其设置为viewholder。为每个viewholder设置一个等于其位置的标记,然后在加载时检查viewholder的标记并查看它是否等于刚刚加载的图像位置,如果它是相同的设置图像其他意味着视图持有人已被回收。将viewholder引用保留为weakreference,并且只要图像准备就绪,请检查持有者是否为空。

进一步优化也是可能的,例如回收bitmap,您可以阅读文档以了解它是如何实现的。

快乐编码: - )