5

現在、廃止された Android のような単純な画像ギャラリーを作成しようとしていますGallery。このギャラリーから、ユーザーはギャラリーから画像を選択することで、単純な画像エディターに移動することもできます。多くのグーグルの後、私はまさに私が必要としているHorizontalListView ここを見つけることができました。最初は、画像を圧縮ビットマップとしてフォルダーに挿入するだけで、これで多くの成功を収めました。それ以来、Google I/Oで画像ギャラリーと画像エディターを作成しているこのビデオを見つけました。私が作成しようとしているものに似ています。ただし、私のアプリと彼らのアプリには主な違いが 2 つあります。

  • 彼らは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);

私の画像が読み込まれない理由についてのアイデアはありますか?

4

1 に答える 1

2

ここでの基本的な問題は、bindView()メソッドが asynctask の結果を待っていないことです。リスト ビューのコンテンツの一部が変更された場合は、リスト ビューに通知する必要があります。

次の変更を行うことができます。

1)これに変更task.execute(photoId);すると、イメージを取得するまでメソッドtask.execute(photoId).get();が強制bindView()的に待機します。このアプローチはお勧めできませんが、正確な問題を理解するのに役立ちます。

また

2) onPost()ofasynctaskで、リスト ビューの古いコンテンツを無効にし、新しいコンテンツで再読み込みを試みます。

mAdapter.notifyDataSetChanged();
mAdapter.notifyDataSetInvalidated();

また

3) 個人的には、まずコード構造を変更してすべてのネットワーク操作 (つまり、画像のフェッチ) を終了し、その後、プリフェッチされたデータを使用してアダプターを設定することをお勧めします。これは完璧な解決策ではありませんが、私の場合はうまくいきました。

于 2012-12-31T12:41:19.213 に答える