无法将缩略图加载到列表视图中。

5
我正在尝试创建一个简单的图像库,就像现在已被弃用的AndroidGallery。用户可以从此库中选择图像并导航到一个简单的图像编辑器。经过大量搜索,我找到了一个HorizontalListView,它是我需要的。您可以在这里找到它。最初,我只需将压缩位图插入我的文件夹即可轻松实现。然而,自那以后,我发现了Google I/O的这个视频,他们创建了一个图像库和一个图像编辑器,类似于我正在尝试创建的内容。然而,我的应用程序与他们的应用程序有两个主要区别:
  • 他们在他们的库中使用GridView,而我使用前面提到的HorizontalListView
  • 我试图仅从指定目标路径加载图像,而不仅仅是SD卡上的所有图像。

到目前为止,我无法将他们的代码适应到我的代码中,因为没有任何图像加载到我的库中。与视频一样,我使用AsyncTask来加载我的缩略图:

    private class ThumbnailAsyncTask extends AsyncTask<Long, Void, Bitmap>
    {
        //The ImageView we will be adding the thumbnail to
        private final ImageView mTarget;

        public ThumbnailAsyncTask(ImageView target)
        {
            mTarget = target;
        }

        @Override
        protected Bitmap doInBackground(Long... params) 
        {
            final long photoID = params[0];

            final Bitmap result = MediaStore.Images.Thumbnails.getThumbnail(
                    getContentResolver(), photoID, MediaStore.Images.Thumbnails.MINI_KIND, null);

            return result;
        }

        @Override
        protected void onPreExecute()
        {
            mTarget.setTag(this);
        }

        @Override
        protected void onPostExecute(Bitmap result)
        {
            if (mTarget.getTag() == this) 
            {
                mTarget.setImageBitmap(result);
                mTarget.setTag(null);
            }
        }   
}

我正在使用CursorAdapter来管理画廊的图片:

   private class PhotoAdapter extends CursorAdapter
   {
    public PhotoAdapter(Context context)
    {
        super(context, null, false);
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) 
    {
        return LayoutInflater.from(context).inflate(R.layout.list_item, parent, false);
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) 
    {
        final long photoId = cursor.getLong(cursor.getColumnIndex(BaseColumns._ID));

        final ImageView imageView = (ImageView) view.findViewById(android.R.id.icon);

        /* 
         * Cancel any pending thumbnail task, since this view is now bound
         * to new thumbnail
         */
        final ThumbnailAsyncTask oldTask = (ThumbnailAsyncTask) imageView.getTag();

        if (oldTask != null) 
            oldTask.cancel(false);    

        /* 
         * If we arrived here, either cache is disabled or cache miss, so we
         * need to kick task to load manually
         */
        final ThumbnailAsyncTask task = new ThumbnailAsyncTask(imageView);
        imageView.setImageBitmap(null);
        imageView.setTag(task);
        task.execute(photoId);
    }
}

使用以下CursorLoader:
    final LoaderCallbacks<Cursor> mCursorCallbacks = new LoaderCallbacks<Cursor>() 
            {
                @Override
                public Loader<Cursor> onCreateLoader(int id, Bundle args) 
                {
                    final String[] columns = {BaseColumns._ID};
                    return new CursorLoader(NewProjectActivity.this,
                            Uri.fromFile(new File(mTargetPath)), columns, null, null,
                            MediaStore.Images.Media.DATE_ADDED + " DESC");
                }

                @Override
                public void onLoadFinished(Loader<Cursor> loader, Cursor data) 
                {
                    mAdapter.swapCursor(data);
                }

                @Override
                public void onLoaderReset(Loader<Cursor> loader) 
                {
                    mAdapter.swapCursor(null);
                }
            };

    getLoaderManager().initLoader(LOADER_CURSOR, null, mCursorCallbacks);

有什么想法,为什么我的图片都无法加载?
1个回答

2
这里的基本问题是,bindView()方法没有等待异步任务的结果。当某些内容发生更改时,您需要通知列表视图。您可以进行以下更改。
1)将task.execute(photoId);更改为task.execute(photoId).get();,这将强制您的bindView()方法等待直到获取图像。这种方法不可取,但它将帮助您了解确切的问题。 或者 2)在asynctaskonPost()中,使您的列表视图的旧内容无效,并尝试使用新内容重新加载它。
mAdapter.notifyDataSetChanged();
mAdapter.notifyDataSetInvalidated();

或者

3) 我个人建议您通过更改代码结构先完成所有网络操作(即获取图像),然后再尝试使用预取的数据设置适配器。这不是一个完美的解决方案,但在我的情况下有效。


我尝试了你的第一个建议,但没有成功,那么我该如何实现你的第二个建议呢?我只需要调用 notifyDataSetChanged() 吗?由于我是 Android 新手,所以请谅解我的问题。 - Kent Hawkings
我按照你的建议重新组织了我的代码,最终让它正常工作了。谢谢 :) - Kent Hawkings

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