0

これは、ViewPager に画像をロードするための BitmapWorkerTask です。画像の読み込みの進行状況を示す UX を向上させるために、各ページに Horizo​​ntal ProgressBar を追加しようとしています。(私はすでに「不確定」な円進行状況バーを使用しています。)

BitmapWorkerTask はプログレス バーを追加するのに適切な場所ですか?

/**
 * The actual AsyncTask that will asynchronously process the image.
 */
private class BitmapWorkerTask extends AsyncTask<Object, Void, Bitmap> {
    private Object data;
    private final WeakReference<ImageView> imageViewReference;

    public BitmapWorkerTask(ImageView imageView) {
        imageViewReference = new WeakReference<ImageView>(imageView);
    }

    /**
     * Background processing.
     */
    @Override
    protected Bitmap doInBackground(Object... params) {            

        data = params[0];
        final String dataString = String.valueOf(data);
        Bitmap bitmap = null;

        // Wait here if work is paused and the task is not cancelled
        synchronized (mPauseWorkLock) {
            while (mPauseWork && !isCancelled()) {
                try {
                    mPauseWorkLock.wait();
                } catch (InterruptedException e) {}
            }
        }

        // If the image cache is available and this task has not been cancelled by another
        // thread and the ImageView that was originally bound to this task is still bound back
        // to this task and our "exit early" flag is not set then try and fetch the bitmap from
        // the cache
        if (mImageCache != null && !isCancelled() && getAttachedImageView() != null
                && !mExitTasksEarly) {
            bitmap = mImageCache.getBitmapFromDiskCache(dataString);
        }

        // If the bitmap was not found in the cache and this task has not been cancelled by
        // another thread and the ImageView that was originally bound to this task is still
        // bound back to this task and our "exit early" flag is not set, then call the main
        // process method (as implemented by a subclass)
        if (bitmap == null && !isCancelled() && getAttachedImageView() != null
                && !mExitTasksEarly) {
            bitmap = processBitmap(params[0]);
        }

        // If the bitmap was processed and the image cache is available, then add the processed
        // bitmap to the cache for future use. Note we don't check if the task was cancelled
        // here, if it was, and the thread is still running, we may as well add the processed
        // bitmap to our cache as it might be used again in the future
        if (bitmap != null && mImageCache != null) {
            mImageCache.addBitmapToCache(dataString, bitmap);
        }            

        return bitmap;
    }

    /**
     * Once the image is processed, associates it to the imageView
     */
    @Override
    protected void onPostExecute(Bitmap bitmap) {
        // if cancel was called on this task or the "exit early" flag is set then we're done
        if (isCancelled() || mExitTasksEarly) {
            bitmap = null;
        }

        final ImageView imageView = getAttachedImageView();
        if (bitmap != null && imageView != null) {
            if (BuildConfig.DEBUG) {
                Log.d(TAG, "onPostExecute - setting bitmap");
            }
            setImageBitmap(imageView, bitmap);
        }
    }

    @Override
    protected void onCancelled(Bitmap bitmap) {
        super.onCancelled(bitmap);
        synchronized (mPauseWorkLock) {
            mPauseWorkLock.notifyAll();
        }
    }

    /**
     * Returns the ImageView associated with this task as long as the ImageView's task still
     * points to this task as well. Returns null otherwise.
     */
    private ImageView getAttachedImageView() {
        final ImageView imageView = imageViewReference.get();
        final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);

        if (this == bitmapWorkerTask) {
            return imageView;
        }

        return null;
    }
}
4

2 に答える 2

0

ビットマップのロード方法を検討する

return BitmapFactory.decodeStream(params[0].openConnection().getInputStream());

実際の進捗率を示すことは不可能です。未定義のプログレスバーの場合、コンストラクターにプログレスバーを渡し、それを別の WeakReference に保存して、コードで次のようにすることができます。

// Before start hide the ImageView and show the progressBar
@Override
protected void onPreExecute(){
    // do the weak reference stuff and call
    progressBar.setVisibility(View.VISIBLE);
    imageView.setVisibility(View.INVISIBLE);
}

// Once complete, see if ImageView is still around and set bitmap.
@Override
protected void onPostExecute(Bitmap bitmap) {
     // do the weak refence stuff and call
    progressBar.setVisibility(View.INVISIBLE);
    imageView.setVisibility(View.VISIBLE);
}
于 2013-04-10T13:04:03.017 に答える
0

さて、ちょうど 4 時間を費やして「不可能」を実行しました。その秘訣は次のとおりです。

  1. BitmapWorkerTask に渡される前に、HTTP URL からイメージをロードするときの進行状況を測定します。このリンクは、そのための優れたチュートリアルです。
  2. 読み込み中の URL メソッドから BitmapWorkerTask クラスに進行状況の更新を渡します。ただし、このメソッドは AsyncTask 内でのみ機能するため、このpublishProgress()に従って回避します。
  3. そして、ニーズに合わせてカスタマイズするためのトラブルシューティング、試行錯誤の数々。

幸運を!これが人々が正しい方向に進むのに役立つことを願っています.

于 2013-04-10T17:54:33.547 に答える