基本的なことですが、どんなパターンが実装可能かとか忘れちゃいがちだったりするので、バリエーション作ってまとめときます。
準備
まずはベースのclass。とにかく詰め込んでるのでかなり長いです。
MyDialogFragment.java
public class MyDialogFragment extends DialogFragment { private static final String TAG = MyDialogFragment.class.getSimpleName(); private static Dialog dialog = null; private boolean isCancelable = true; // TODO: デフォルトを設定 private String title = ""; private String message = ""; private String positiveLabel = ""; private DialogInterface.OnClickListener onPositiveButtonClickListener = new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Log.w(TAG, "click positive"); } }; private String negativeLabel = ""; private DialogInterface.OnClickListener onNegativeButtonClickListener = new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Log.v(TAG, "click negative"); } }; private String neutralLabel = ""; private DialogInterface.OnClickListener onNeutralButtonClickListener = new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Log.v(TAG, "click neutral"); } }; private CharSequence[] items = null; private int checkedSingleChoiceItemPosition = -1; private CharSequence[] singleChoiceItems = null; // items or singleChoiceItemsの選択 private DialogInterface.OnClickListener onItemClickListener = new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Log.v(TAG, "click item which: " + which); checkedSingleChoiceItemPosition = which; } }; private boolean[] checkedMultiChoiceItemsPosition = null; private CharSequence[] multiChoiceItems = null; private DialogInterface.OnMultiChoiceClickListener onMultiChoiceItemClickListener = new DialogInterface.OnMultiChoiceClickListener() { @Override public void onClick(DialogInterface dialog, int which, boolean isChecked) { Log.v(TAG, "click item which: " + which + ", isChecked: " + isChecked); checkedMultiChoiceItemsPosition[which] = isChecked; } }; private View dialogView = null; private CheckBox checkBox = null; private EditText editText = null; public MyDialogFragment() { } // キャンセル有効 public MyDialogFragment validCancel() { this.isCancelable = true; return this; } // キャンセル無効 public MyDialogFragment invalidCancel() { this.isCancelable = false; return this; } // タイトルを設定 public MyDialogFragment setTitle(String title) { this.title = title; return this; } // メッセージを設定 public MyDialogFragment setMessage(String message) { this.message = message; return this; } // Positiveな選択肢の表示名(設定しなくてもデフォルト値で表示) public MyDialogFragment setPositiveLabel(String positiveLabel) { this.positiveLabel = positiveLabel; return this; } // Positive選択時の処理 public MyDialogFragment setOnPositiveButtonClickListener(DialogInterface.OnClickListener listener) { this.onPositiveButtonClickListener = listener; return this; } // Negativeな選択肢の表示名 public MyDialogFragment setNegativeLabel(String negativeLabel) { this.negativeLabel = negativeLabel; return this; } // Negative選択時の処理 public MyDialogFragment setOnNegativeButtonClickListener(DialogInterface.OnClickListener listener) { this.onNegativeButtonClickListener = listener; return this; } // Neutralな選択肢の表示名 public MyDialogFragment setNeutralLabel(String neutralLabel) { this.neutralLabel = neutralLabel; return this; } // Neutral選択時の処理 public MyDialogFragment setOnNeutralButtonClickListener(DialogInterface.OnClickListener listener) { this.onNeutralButtonClickListener = listener; return this; } // リストを設置 public MyDialogFragment setItems(CharSequence[] items) { this.items = items; return this; } // リストでアイテム選択時の処理 public MyDialogFragment setOnItemClickListener(DialogInterface.OnClickListener listener) { this.onItemClickListener = listener; return this; } // SingleChoiceItemsを設置 public MyDialogFragment setSingleChoiceItems(CharSequence[] singleChoiceItems, int checkedItemPosition) { this.singleChoiceItems = singleChoiceItems; // 初期選択アイテムの位置 this.checkedSingleChoiceItemPosition = checkedItemPosition; return this; } // SingleChoiceItemsのアイテム選択時の処理(必須ではない) public MyDialogFragment setOnSingleChoiceItemListener(DialogInterface.OnClickListener listener) { this.onItemClickListener = listener; return this; } // setOnSingleChoiceItemListenerを自分で設定した場合に、保持するポジションも変更 public MyDialogFragment setCheckedSingleChoiceItem(int position) { this.checkedSingleChoiceItemPosition = position; return this; } // SingleChoiceItemsで選択中のアイテムの位置 public int getCheckedSingleChoiceItemPosition() { return this.checkedSingleChoiceItemPosition; } // SingleChoiceItemsで選択中のアイテム public String getCheckedSingleChoiceItem() { return this.singleChoiceItems[getCheckedSingleChoiceItemPosition()].toString(); } // MultiChoiceItemsを設置 public MyDialogFragment setMultiChoiceItems(CharSequence[] multiChoiceItems, boolean[] checkedMultiChoiceItems) { this.multiChoiceItems = multiChoiceItems; // 初期選択アイテムの位置 this.checkedMultiChoiceItemsPosition = checkedMultiChoiceItems; return this; } // MultiChoiceItemsのアイテム選択時の処理(必須ではない) public MyDialogFragment setOnMultiChoiceItemListener(DialogInterface.OnMultiChoiceClickListener onMultiChoiceItemClickListener) { this.onMultiChoiceItemClickListener = onMultiChoiceItemClickListener; return this; } // setOnMultiChoiceItemListenerを自分で設定した場合に、保持するポジションも変更 public MyDialogFragment setCheckedMultiChoiceItem(int position, boolean isChecked) { this.checkedMultiChoiceItemsPosition[position] = isChecked; return this; } // MultiChoiceItemsで選択中のアイテムの位置 public boolean[] getCheckedMultiChoiceItemsPosition() { return this.checkedMultiChoiceItemsPosition; } // MultiChoiceItemsで選択中のアイテム public List<String> getCheckedMultiChoiceItems() { List<String> items = new ArrayList<>(); for (int i = 0; i < this.multiChoiceItems.length; i++) { if (this.checkedMultiChoiceItemsPosition[i]) { items.add(this.multiChoiceItems[i].toString()); } } return items; } // 指定のレイアウトを設置 public MyDialogFragment setView(Context c, int layoutId) { LayoutInflater adbInflater = LayoutInflater.from(c); this.dialogView = adbInflater.inflate(layoutId, null); return this; } // 画像を設置 public MyDialogFragment setImageView(Context c, int drawableId) { LayoutInflater adbInflater = LayoutInflater.from(c); this.dialogView = adbInflater.inflate(R.layout.dialog_parts_iv, null); ImageView iv = (ImageView) dialogView.findViewById(R.id.iv); iv.setImageResource(drawableId); return this; } // EditTextの設置 public MyDialogFragment setEditText(Context c, String initialValue) { LayoutInflater adbInflater = LayoutInflater.from(c); this.dialogView = adbInflater.inflate(R.layout.dialog_parts_et, null); this.editText = (EditText) dialogView.findViewById(R.id.et); this.editText.setText(initialValue); return this; } // EditTextの入力値 public String getEditText() { if (this.editText == null) { return ""; } return this.editText.getText().toString(); } // 数値限定のEditTextを設置 public MyDialogFragment setEditTextInputNumber(Context c, int initialValue) { setEditText(c, String.valueOf(initialValue)); this.editText.setInputType(InputType.TYPE_CLASS_NUMBER); return this; } // 数値限定のEditTextの入力値 public int getEditTextInt() { if (this.editText == null) { return 0; } return Integer.parseInt(this.editText.getText().toString()); } // チェックボックスの設置 public MyDialogFragment setCheckBox(Context c) { LayoutInflater adbInflater = LayoutInflater.from(c); this.dialogView = adbInflater.inflate(R.layout.dialog_parts_checkbox, null); checkBox = (CheckBox) dialogView.findViewById(R.id.checkbox); return this; } // チェックボックスのチェック public boolean getCheckBox() { if (checkBox == null) { return false; } return checkBox.isChecked(); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setRetainInstance(true); } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { setCancelable(isCancelable); // Fragmentに対して設定 AlertDialog.Builder dlgBuilder = new AlertDialog.Builder(getActivity()); if (!title.equals("")) { dlgBuilder.setTitle(title); } if (!message.equals("")) { dlgBuilder.setMessage(message); } if (items != null) { dlgBuilder.setItems(items, onItemClickListener); } if (singleChoiceItems != null) { dlgBuilder.setSingleChoiceItems(singleChoiceItems, checkedSingleChoiceItemPosition, onItemClickListener); } if (multiChoiceItems != null) { dlgBuilder.setMultiChoiceItems(multiChoiceItems, checkedMultiChoiceItemsPosition, onMultiChoiceItemClickListener); } if (dialogView != null) { dlgBuilder.setView(dialogView); } // positiveLabelは空でもデフォルト値を指定して表示 if (positiveLabel.equals("")) { positiveLabel = getString(R.string.dialog_positive); // TODO: デフォルトを設定 } if (items == null) { // setItemの場合にボタンが必要ならNegativeをセット dlgBuilder.setPositiveButton(positiveLabel, onPositiveButtonClickListener); } // Negativeは指定がなければ非表示 if (!negativeLabel.equals("")) { dlgBuilder.setNegativeButton(negativeLabel, onNegativeButtonClickListener); } // Neutralは指定がなければ非表示 if (!neutralLabel.equals("")) { dlgBuilder.setNeutralButton(neutralLabel, onNeutralButtonClickListener); } dlgBuilder.setCancelable(isCancelable); // 多分、意味ないけど一応 dialog = dlgBuilder.create(); dialog.setCanceledOnTouchOutside(isCancelable); // ダイアログ外タップもsetCancelableと共通で設定 return dialog; } @Override public void onDestroyView() { if (getDialog() != null && getRetainInstance()) { getDialog().setDismissMessage(null); } super.onDestroyView(); } // ダイアログを非表示にする public static void dissmissDialog() { if (dialog != null && dialog.isShowing()) { dialog.dismiss(); } } }
このclassで使っているlayout.xmlをいくつか
res/layout/dialog_parts_iv.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:paddingLeft="@dimen/mg_l" android:paddingRight="@dimen/mg_l"> <ImageView android:id="@+id/iv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:contentDescription="@string/empty"/> </LinearLayout>
res/layout/dialog_parts_et.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingLeft="@dimen/mg_l" android:paddingRight="@dimen/mg_l"> <EditText android:id="@+id/et" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="text"/> </LinearLayout>
res/layout/dialog_parts_checkbox.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingLeft="@dimen/mg_m" android:paddingRight="@dimen/mg_m"> <CheckBox android:id="@+id/checkbox" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/dialog_checkbox"/> </LinearLayout>
実装
アラートダイアログ
とりあえず最小限の構成で
new MyDialogFragment() .setMessage("メッセージ") .show(getFragmentManager(), "myDialogTag");
setMessage()を、setTitle()にしてもらってもいいかも
Activity以外ではgetFragmentManager()前にActivityをセットする(以降は省略)
new MyDialogFragment() .setMessage("メッセージ") .show(((Activity) context).getFragmentManager(), "myDialogTag");
確認ダイアログ
適宜、Positive、Negative、Neutralのラベルやクリックリスナーを設定
内容によってはキャンセルできなくするとか
new MyDialogFragment() .invalidCancel() .setTitle("タイトル") .setMessage("よいでしょうか?") .setPositiveLabel("Yes") .setOnPositiveButtonClickListener(new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Toast.makeText(getApplicationContext(), "Yes", Toast.LENGTH_SHORT).show(); } }) .setNegativeLabel("No") .setOnNegativeButtonClickListener(new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Toast.makeText(getApplicationContext(), "No", Toast.LENGTH_SHORT).show(); } }) .show(getFragmentManager(), "myDialogTag");
リストから選択
選択肢を用意してユーザーが選ぶ
final String[] items = {"選択肢1", "選択肢2", "選択肢3", "選択肢4"}; new MyDialogFragment() .setTitle("setItems") .setItems(items) .setOnItemClickListener(new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Toast.makeText(getApplicationContext(), items[which], Toast.LENGTH_SHORT).show(); } }) .show(getFragmentManager(), "myDialogTag");
ラジオボタン付きリスト
性能的には前のリストと近いけど、前回の設定とかを見せるのにはこっちの方が便利
final String[] items = {"選択肢1", "選択肢2", "選択肢3", "選択肢4"}; final int checkedItem = 0; // 未選択は-1 final MyDialogFragment mDialog = new MyDialogFragment(); mDialog .setTitle("setSingleChoiceItems") .setSingleChoiceItems(items, checkedItem) .setOnSingleChoiceItemListener(new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { mDialog.setCheckedSingleChoiceItem(which); Toast.makeText(getApplicationContext(), mDialog.getCheckedSingleChoiceItem() + "を選択", Toast.LENGTH_SHORT).show(); } }) .setOnPositiveButtonClickListener(new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Toast.makeText(getApplicationContext(), mDialog.getCheckedSingleChoiceItem(), Toast.LENGTH_SHORT).show(); } }) .show(getFragmentManager(), "myDialogTag");
チェックボックス付きリスト
複数、選べる
final String[] items = {"選択肢1", "選択肢2", "選択肢3", "選択肢4"}; final boolean[] checked = {true, false, true, false}; // 初期値が未選択ならnullでOK final MyDialogFragment mDialog = new MyDialogFragment(); mDialog .setTitle("setMultiChoiceItems") .setMultiChoiceItems(items, checked) .setOnMultiChoiceItemListener(new DialogInterface.OnMultiChoiceClickListener() { @Override public void onClick(DialogInterface dialog, int which, boolean isChecked) { Log.v(TAG, "click item which: " + which + ", isChecked: " + isChecked); mDialog.setCheckedMultiChoiceItem(which, isChecked); } }) .setOnPositiveButtonClickListener(new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { String checkedItems = ""; for (int i = 0; i < mDialog.getCheckedMultiChoiceItems().size(); i++) { checkedItems += mDialog.getCheckedMultiChoiceItems().get(i) + " "; } if (checkedItems.equals("")) { checkedItems = "未選択"; } Toast.makeText(getApplicationContext(), checkedItems, Toast.LENGTH_SHORT).show(); } }) .show(getFragmentManager(), "myDialogTag");
ImageViewを設置
ダイアログに作成したレイアウトを設置
今回はImageViewを置いて画像を表示
new MyDialogFragment() .setTitle("ImageViewを設置") .setImageView(this, R.mipmap.ic_launcher) .show(getFragmentManager(), "myDialogTag");
EditTextを設置
今度はEditTextを配置
final MyDialogFragment mDialog = new MyDialogFragment(); mDialog .setTitle("EditTextを設置") .setEditText(this, "初期値") .setOnPositiveButtonClickListener(new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Toast.makeText(getApplicationContext(), "input: " + mDialog.getEditText(), Toast.LENGTH_SHORT).show(); } }) .show(getFragmentManager(), "myDialogTag");
CheckBoxを設置
更にチェックボックスを配置
final MyDialogFragment mDialog = new MyDialogFragment(); mDialog .setTitle("CheckBoxを設置") .setCheckBox(this) .setOnPositiveButtonClickListener(new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { boolean check = mDialog.getCheckBox(); Toast.makeText(getApplication(), "check: " + check, Toast.LENGTH_SHORT).show(); } }) .show(getFragmentManager(), "myDialogTag");
とりあえずこんな感じで