Categories
SugiBlog ホームページ制作・システム開発

画像の非同期読み込み

画像を表示する際、読み込み完了までプログレスバーを表示させたい。
ユーザービリティを考慮し、非同期にて実装する方法を書きます。

まずXMLにProgressBarとImageViewを用意します。

<ProgressBar 
  android:id="@+id/progressBar"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  style="?android:attr/progressBarStyle"
  android:layout_gravity="center_vertical|center_horizontal"
  />
<ImageView
  android:id="@+id/imageView1"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:visibility="gone" />


【AsyncTaskを継承したクラスを作成】

public class ImagingTask extends AsyncTask<String, Void, Bitmap> {

  private ImageView imageView; // アイコンを表示するビュー
  private ProgressBar progressBar; // プログレスバー

  // コンストラクタ
  public ImagingTask(ImageView imageView, ProgressBar progressBar) {
    this.imageView = imageView;
    this.progressBar = progressBar;
  }

  // バックグラウンドで実行する処理
  @Override
  protected Bitmap doInBackground(String... filepath) {
    Bitmap image;

    BitmapFactory.Options bmOp = new BitmapFactory.Options();
    bmOp.inSampleSize = 16;

    image = BitmapFactory.decodeFile(filepath[0], bmOp);

    return image;
  }

  // メインスレッドで実行する処理
  @Override
  protected void onPostExecute(Bitmap result) {
    this.imageView.setImageBitmap(result);
    this.imageView.setVisibility(View.VISIBLE);
    this.progressBar.setVisibility(View.GONE);
  }
}

【実行の処理】

ProgressBar progressBar;
progressBar = (ProgressBar)findViewById(R.id.progressBar);

// CustomDataのデータをViewの各Widgetにセットする
ImageView imageView;
imageView = (ImageView)findViewById(R.id.imageView1);

ImagingTask itask = new ImagingTask(imageView, progressBar);
itask.execute("ファイル名");

executeを実行すると、以下の順番で処理が呼ばれます。

1.onPreExecute()
実行前の準備処理

2.doInBackground(Params…)
バックグラウンドで実行したい処理

3.onProgressUpdate(Progress…)
バックグラウンド処理の進捗状況をメインスレッドで表示させたい場合にはここに処理を書きます

4.onPostExecute(Result)
バックグラウンド処理が終了し、メインスレッドに反映させる処理

String、Void、Bitmapの3つの型は順にParams、Progress、Resultとして扱われます。
Params…バックグラウンド処理を開始するインスタンスメソッドexecuteの引数の型
Progress…進捗度合を表示する時に利用したい型
Result…バックグラウンド処理完了時に受け取る型

進捗状況を処理したい場合は、Progressの型をIntegerにし
以下のメソッドを追加します。

@Override
protected void onProgressUpdate(Integer... values) {
  Log.d(TAG, "onProgressUpdate - " + values[0]);
  dialog.setProgress(values[0]); //ダイアログ等の処理
}

進捗を更新するにはdoInBackground内で

publishProgress(Integer i);

キャンセル処理を受け付けたい場合は、OnCancelListenerをimplementsし実装します。
ProgressDialogで実装している場合の例

// implements
// android.content.DialogInterface.OnCancelListener

@Override
protected void onCancelled() {
    progressDialog.dismiss();
}

@Override
public void onCancel(DialogInterface dialog) {
    this.cancel(true);
}

参考にさせていただいたURL
http://labs.techfirm.co.jp/android/cho/1079
http://android.keicode.com/basics/async-asynctask.php
http://lablog.lanche.jp/archives/220

3,920 views

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*