画面回転、キャンセル対応のProgress DialogFragment

画面回転および、キャンセルボタンの有無に対応した、DialogFragment
ProgressDialog 表示を行うものを作成した。

一般的な以下のような表示と、、、

f:id:posturan:20160313194326p:plain



キャンセルボタンボタンが着いた以下のような表示、、、

f:id:posturan:20160313194320p:plain



これら、両方に対応(いわゆるダブルスタンダード)の、DialogFragment で、
ProgressDialog を表示する。

import java.io.Serializable;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.os.Bundle;
/**
 * ProgressDialogFragment
 */

public class ProgressDialogFragment extends DialogFragment{
   // Bundle でタイトル、メッセージ、プログレス最大値、を取得する為の Key
   public final static String TITLE   = "Title";
   public final static String MESSAGE = "Message";
   public final static String MAX     = "Max";
   public final static String CANCELABLE     = "Cancelable";
   public final static String CANCEL_LISTNER = "Cancel_Listener";
   public final static String CANCEL_BUTTON  = "CancelButton";


   public static ProgressDialogFragment newInstance(){
      return new ProgressDialogFragment();
   }

   // キャンセルリスナ、キャンセルボタン有りの時は、
   //   Bundle#putSerializable(CANCEL_LISTNER, cancelListener) でセットする

   public interface CancelListener extends Serializable{
      public void canceled(DialogInterface _interface);
   }


   private static ProgressDialog progressDialog;

   static CancelListener listener;

   @Override
   public Dialog onCreateDialog(Bundle savedInstanceState){
      setCancelable(getArguments().getBoolean(CANCELABLE, false));
      listener = (CancelListener)getArguments().getSerializable(CANCEL_LISTNER);
      if (progressDialog != null) return progressDialog;
      progressDialog = new ProgressDialog(getActivity());
      progressDialog.setTitle(getArguments().getString(TITLE));
      progressDialog.setMessage(getArguments().getString(MESSAGE));
      progressDialog.setIndeterminate(false);
      progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
      progressDialog.setMax(getArguments().getInt(MAX));
      progressDialog.setProgress(0);
      String cancelButton = getArguments().getString(CANCEL_BUTTON, null);
      if (cancelButton != null){

         progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, getArguments().getString(CANCEL_BUTTON), new DialogInterface.OnClickListener(){
            @Override
            public void onClick(DialogInterface dialog, int which){
               listener.canceled(dialog);
            }
         });
      }

      return progressDialog;
   }
   public void updateProgress(int value){
      if (progressDialog != null) progressDialog.setProgress(value);
   }
   @Override
   public Dialog getDialog(){
      return progressDialog;
   }
   @Override
   public void onCancel(DialogInterface dialog){
      if (getArguments().getBoolean(CANCELABLE, false)){
         listener.canceled(dialog);
      }

   }
   @Override
   public void onDestroy(){
      super.onDestroy();
      progressDialog = null;
   }

}
-----------------------------------------------------
(使い方)AsyncTask で呼び出す。

====【キャンセル無しの場合】====

public class NoCancelTask extends AsyncTask<String,Integer,Long>{
   private Activity activity;
   ProgressDialogFragment d_fragment;

   public NoCancelTask1(Activity activity){
      this.activity = activity;
   }
   @Override
   protected void onPreExecute(){
      Bundle args = new Bundle();
      args.putString(ProgressDialogFragment.TITLE, "Title");
      args.putString(ProgressDialogFragment.MESSAGE, "Loading Data ...");
      args.putInt(ProgressDialogFragment.MAX, 100);
      d_fragment = ProgressDialogFragment.newInstance();
      d_fragment.setArguments(args);
      d_fragment.show(activity.getFragmentManager(), "progress");
   }
   @Override
   protected Long doInBackground(String...params){
      ・・・・・・
   }
   @Override
   protected void onProgressUpdate(Integer...values){
      d_fragment.updateProgress(values[0]);
   }
   @Override
   protected void onPostExecute(Long result){
      ・・・・・・・・
      // 終わったら消滅させる。
      d_fragment.getDialog().dismiss();

   }
}


====【キャンセルボタン有りの場合】====


public class CancelButonOrBackKeyTask extends AsyncTask<String,Integer,Long>{
   private Activity activity;
   private ProgressDialogFragment d_fragment;
   private boolean cancelFlag = false;

   public CancelButonOrBackKeyTask(Activity activity){
      this.activity = activity;
   }
   @Override
   protected void onPreExecute(){
      Bundle args = new Bundle();
      args.putString(ProgressDialogFragment.TITLE, "Title");
      args.putString(ProgressDialogFragment.MESSAGE, "Loading Data ...");
      args.putInt(ProgressDialogFragment.MAX, 100);
      args.putBoolean(ProgressDialogFragment.CANCELABLE, true);
      args.putString(ProgressDialogFragment.CANCEL_BUTTON, "キャンセル");
      args.putSerializable(ProgressDialogFragment.CANCEL_LISTNER, new ProgressDialogFragment.CancelListener(){
         @Override
         public void canceled(DialogInterface _interface){

            // キャンセルを この AsyncTask に通知
            cancel(true);

         }
      });
      d_fragment = ProgressDialogFragment.newInstance();
      d_fragment.setArguments(args);
      d_fragment.show(activity.getFragmentManager(), "progress");
   }
   @Override
   protected Long doInBackground(String...params){
      ・・・・・・
   }
   @Override
   protected void onProgressUpdate(Integer...values){
      d_fragment.updateProgress(values[0]);
   }
   @Override
   protected void onPostExecute(Long result){
      ・・・・・・
      // 終わったら消滅させる。
      d_fragment.getDialog().dismiss();

   }
   @Override
   protected void onCancelled(){
      cancelFlag = true;
      Toast.makeText(activity, "キャンセルされました", Toast.LENGTH_SHORT).show();
   }
}