DialogFragment に CancelListner

以前、シンプルな使い回しのメッセージを出すだけの DialogFragment を書いた。
http://blog.zaq.ne.jp/oboe2uran/article/875/
この当時は、キャンセル時に、CancelListner を登録しておいて動かそうとは思わなかった。
DialogFragment onCreateDialog で、AlertDialog.Builder の setOnCancelListener
実行すると、例外になってしまう。

IllegalStateException: You can not set Dialog's OnCancelListener or OnDismissListener

よくよく、AndroidAPI ドキュメント、DialogFragment の説明を見ると、、

Note: DialogFragment own the Dialog.setOnCancelListener and Dialog.setOnDismissListener callbacks.
You must not set them yourself. To find out about these events, override onCancel(DialogInterface)
 and onDismiss(DialogInterface).


自分で、onCancel override しなさいと。。。

public class SimpleMessageDialog extends DialogFragment

というのを用意するなら、生成時に

 
DialogFragment = new SimpleMessageDialog(){
   @Override
   public void onCancel(DialogInterface dialog){
      // キャンセル時の処理
   }
};


ということなんだけど、キャンセル時の処理のステップが多いとちょっと嫌だ。
リスナを用意したい。

http://blog.zaq.ne.jp/oboe2uran/article/875/ で書いたものを
書き直すことにした。

=================== SimpleDialogInterface =================================
import java.io.Serializable;
/**
 * SimpleDialogInterface
 */

public interface SimpleDialogInterface extends Serializable{
   public final static String MESSAGE = "Message";
   public final static String TITLE   = "Title";
   public final static String CANCELABLE   = "Cancelable";
   public final static int POSITIVE = 0;
   public final static int NEGATIVE = 1;
   public final static int NEUTRAL  = 2;
   public final static String POSITIVE_LABEL   = "PositiveLabel";
   public final static String NEGATIVE_LABEL   = "NegativeLabel";
   public final static String NEUTRAL_LABEL    = "NeutralLabel";
   public final static String LISTENER         = "Listener";
   public final static String CANCEL_LISTNER = "Cancel_Listener";
   public final static String DISMISSL_LISTNER = "dismiss_Listener";


   /**
    * Dialog Button on Click
    * @param which 各ボタンが押された時の判断として以下の値を返す
    * PositiveButton → 0 = SimpleDialogInterface.POSITIVE
    * NegativeButton → 1 = SimpleDialogInterface.NEGATIVE
    * NeutralButton  → 2 = SimpleDialogInterface.NEUTRAL
    */

   public void onButtonClick(int which);
}

=================== SimpleMessageDialog =================================

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

public class SimpleMessageDialog extends DialogFragment{

   public interface CancelListener extends Serializable{
      public void canceled(DialogInterface _interface);
   }
   private CancelListener cancelListener = new CancelListener(){
      @Override
      public void canceled(DialogInterface _interface){
      }
   };
   public interface DismisslListener extends Serializable{
      public void dismissed(DialogInterface _interface);
   }
   private DismisslListener dismissListener = new DismisslListener(){
      @Override
      public void dismissed(DialogInterface _interface){
      }
   };


   @Override
   public Dialog onCreateDialog(Bundle savedInstanceState){
      AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
      Bundle bundle = getArguments();
      builder.setTitle(bundle.getString(SimpleDialogInterface.TITLE, null));
      String message = bundle.getString(SimpleDialogInterface.MESSAGE, null);
      if (message != null) builder.setMessage(message);
      setCancelable(getArguments().getBoolean(SimpleDialogInterface.CANCELABLE, true));
      String positiveLabel = bundle.getString(SimpleDialogInterface.POSITIVE_LABEL, null);
      String negativeLabel = bundle.getString(SimpleDialogInterface.NEGATIVE_LABEL, null);
      String neutralLabel = bundle.getString(SimpleDialogInterface.NEUTRAL_LABEL, null);
      if (positiveLabel != null || negativeLabel != null || neutralLabel != null){
         final SimpleDialogInterface simpleface = (SimpleDialogInterface)bundle.getSerializable(SimpleDialogInterface.LISTENER);
         if (positiveLabel != null){
            builder.setPositiveButton(positiveLabel, new DialogInterface.OnClickListener(){
               @Override
               public void onClick(DialogInterface dialog, int which){
                  simpleface.onButtonClick(SimpleDialogInterface.POSITIVE);
               }
            });
         }
         if (negativeLabel != null){
            builder.setNegativeButton(negativeLabel, new DialogInterface.OnClickListener(){
               @Override
               public void onClick(DialogInterface dialog, int which){
                  simpleface.onButtonClick(SimpleDialogInterface.NEGATIVE);
               }
            });
         }
         if (neutralLabel != null){
            builder.setNeutralButton(neutralLabel, new DialogInterface.OnClickListener(){
               @Override
               public void onClick(DialogInterface dialog, int which){
                  simpleface.onButtonClick(SimpleDialogInterface.NEUTRAL);
               }
            });
         }
      }
      if (bundle.containsKey(SimpleDialogInterface.CANCEL_LISTNER)){
         cancelListener = (CancelListener)bundle.getSerializable(SimpleDialogInterface.CANCEL_LISTNER);
      }
      if (bundle.containsKey(SimpleDialogInterface.DISMISSL_LISTNER)){
         dismissListener = (DismisslListener)bundle.getSerializable(SimpleDialogInterface.DISMISSL_LISTNER);
      }

      return builder.create();
   }
   @Override
   public void onCancel(DialogInterface _dialog){
      super.onCancel(_dialog);
      cancelListener.canceled(_dialog);
   }
   @Override
   public void onDismiss(DialogInterface dialog){
      super.onDismiss(dialog);
      dismissListener.dismissed(dialog);
   }

}