【Android】DialogFragmentを使ってみる
こんにちは。
前回、こちらのエントリーでAlertDialogについて触れました。
このエントリーの最後にも書いてあるのですが、現在はDialogFragmentが推奨されており、こちらを使うのが良いようです。
そこで、今回はこれを使ってAlertDialogとProgressDialogを出してみたいと思います。 最初は癖がありますが、慣れるとそれほど難しくありません。
AlertDialogを出す
まずはAlertDialogです。 はじめに、DialogFragmentを継承するクラスを作成します。
なお、今回はOKボタンやCancelボタンが押されたかのイベントをActivity側に返すために、Listenerを作成しています。
import android.app.AlertDialog; import android.app.Dialog; import android.content.DialogInterface; import android.os.Bundle; // ここは要注意。 // import android.support.v4.app.DialogFragment;だとうまくいかないので、必ず以下にする。 import android.app.DialogFragment; public class MyDialogFragment extends DialogFragment{ private DialogListener listener = null; /** * ファクトリーメソッド * @param type ダイアログタイプ 0:OKボタンのみ 1:OK, NGボタン */ public static MyDialogFragment newInstance(String title, String message, int type){ MyDialogFragment instance = new MyDialogFragment(); // ダイアログに渡すパラメータはBundleにまとめる Bundle arguments = new Bundle(); arguments.putString("title", title); arguments.putString("message", message); arguments.putInt("type", type); instance.setArguments(arguments); return instance; } /** * AlertDialog作成 */ @Override public Dialog onCreateDialog(Bundle savedInstanceState){ String title = getArguments().getString("title"); String message = getArguments().getString("message"); int type = getArguments().getInt("type"); AlertDialog.Builder alert = new AlertDialog.Builder(getActivity()) .setTitle(title) .setMessage(message) .setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // OKボタンが押された時 listener.doPositiveClick(); dismiss(); } }); if (type == 1){ // NGボタンも付ける場合 alert.setNegativeButton("キャンセル", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // Cancelボタンが押された時 listener.doNegativeClick(); dismiss(); } }); } return alert.create(); } /** * リスナーを追加 */ public void setDialogListener(DialogListener listener){ this.listener = listener; } /** * リスナー削除 */ public void removeDialogListener(){ this.listener = null; } }
注意してほしいのはコード上にも書きましたが、インポートの部分です。 それ以外は難しいことはしていません。 そして、リスナーで対象Activityのリスナーをセットしています。
次にそのリスナーインターフェースを作成します。
import java.util.EventListener; public interface DialogListener extends EventListener{ /** * OKボタンが押されたイベントを通知 */ public void doPositiveClick(); /** * Cancelボタンが押されたイベントを通知 */ public void doNegativeClick(); }
ここは特に何もありません。 次に行きます。
次はActivity側です。 Activityではダイアログを表示するShow関数、OKボタン、Cancelボタンが押された時の処理をする関数をそれぞれ定義します。 以下のコードでは、これらの関数の定義部分以外は省略します。
public class MainActivity extends Activity implements DialogListener{ // DialogListener をImplementsしておくこと /** * ダイアログ表示関数 * @param type ダイアログタイプ 0:OKボタンのみ 1:OK, NGボタン */ public void showDialog(String title, String message, int type){ MyDialogFragment newFragment = MyDialogFragment.newInstance(title, message, type); // リスナーセット newFragment.setDialogListener(this); // ここでCancelable(false)をしないと効果が無い newFragment.setCancelable(false); newFragment.show(getFragmentManager(), "dialog"); } /** * OKボタンをおした時 */ public void doPositiveClick() { finish(); } /** * NGボタンをおした時 */ @Override public void doNegativeClick() { } }
注意点としては、以下のとおりです。
- DialogListenerをImplementsしておくこと
- バックボタンなどでアラートを閉じさせたくない時には、DialogFragment#setCancelable()をしないと動かないので、Activity側で呼び出すようにすること(MyDialogFragmentの中でやっても意味ない)
あとはアラートダイアログを表示させたい場所でshowDialog()を呼び出せばOKです。
ProgressDialogを出す
次にProgressDialogです。 前にこちらのエントリーでProgressDialogの出し方を書きましたが、これをDialogFragmentで出したいと思います。
今回は、円スタイルのDialogにします。 プログレスバーの方のやり方は後々書ければ書きたいと思いますが、参考サイトにも書いてあるし、やり方もあまり変わらないので特に問題ないとは思います。
それでは早速コードです。 分かりやすいように、上のAlertDialogのDialogFragmentとは別のFragmentを作成します。
import android.app.Dialog; import android.app.DialogFragment; import android.app.ProgressDialog; import android.os.Bundle; public class MyProgressDialogFragment extends DialogFragment{ private static ProgressDialog progressDialog = null; // インスタンス生成はこれを使う public static MyProgressDialogFragment newInstance(String title, String message){ MyProgressDialogFragment instance = new MyProgressDialogFragment(); // ダイアログにパラメータを渡す Bundle arguments = new Bundle(); arguments.putString("title", title); arguments.putString("message", message); instance.setArguments(arguments); return instance; } // ProgressDialog作成 @Override public Dialog onCreateDialog(Bundle savedInstanceState){ if (progressDialog != null) return progressDialog; // パラメータを取得 String title = getArguments().getString("title"); String message = getArguments().getString("message"); progressDialog = new ProgressDialog(getActivity()); progressDialog.setTitle(title); progressDialog.setMessage(message); progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); // プログレスダイアログのスタイルを円スタイルに設定 // プログレスダイアログのキャンセルが可能かどうかを設定(バックボタンでダイアログをキャンセルできないようにする) setCancelable(false); return progressDialog; } // progressDialog取得 @Override public Dialog getDialog(){ return progressDialog; } // ProgressDialog破棄 @Override public void onDestroy(){ super.onDestroy(); progressDialog = null; } }
以上です。
基本的にAlertDialogのFragmentと違いはありません。 注意すべきところとして、onDestroy()をOverrideしておかないと、Dismissしたときに落ちるので、必ずするようにしましょう。
そして、使いたいActivityなどで以下のようにして呼び出します。
MyProgressDialogFragment progressDialog; // ロード中画面のプログレスダイアログ作成 progressDialog = MyProgressDialogFragment.newInstance("ネットワークに接続中です", "しばらくお待ちください"); // Dialog表示 progressDialog.show(getFragmentManager(), "progress"); // Dialog終了 progressDialog.getDialog().dismiss();
こんな感じです。簡単ですね。 Dialogを終了するとき、getDialog()してからdismiss()するようにしないと落ちるので気をつけてください。
以上です。 これでDialogFragmentに対応することが出来たかなと思います。 少し癖があるように感じますが、慣れるとそれほど難しくはなさそうです。 Dialogに関しては、Fragmentを推奨しているので、積極的に使っていきましょう。
それでは。
参考にさせていただいたサイト
DialogFragment | Android Developers
DialogFragmentでシンプルで汎用的なダイアログ
Code
DialogFragmentではsetCancelableはフラグメントに対して行う
画面回転、キャンセル対応のProgress DialogFragment
DialogFragment の dismiss で落ちる