DialogFragmentでシンプルで汎用的なダイアログ
自分用のメモです。
AlertDialogをダイアログ表示処理に使っていましたが非推奨になったので
DialogFragmentを使うことにしました。
参考にさせていただいたサイトさま
何故DialogFragmentか
Why DialogFragment can't be an inner class?
DialogFragmentを継承したクラスを作成してその中にダイアログがクリックされた
処理を書けば呼び出し側もソースがすっきりします。
でもちょっとした処理でいちいちソースファイルを増やしたくないし
君はokかキャンセルかだけ返してくれれば後はこっちで処理するからってことも
多いので、使いまわせるシンプルなDialogFragment継承クラスを作ることにしました。
上記の参考サイトさまにも「ActivityやFragmentに専用のInterfaceを実装する」
との項目がありますが、コールバックインタフェースを使って、
okかcancelかのイベントだけ取って後は呼び出し元で処理を行います。
呼び出し元内で複数DialogFragmentを使う時はコールバックメソッドの引数に
リクエストコード的なものを渡してやるように変えればどこから呼び出したかわかりますね。
ところでgistにあるコードを埋め込みたいんだけどうまくいかないです(;´Д`)
何でだかわからない(;´Д`)
【2013/09/30追記】 gistのスクリプトを貼り付ける時にsrc=の後ろのURLに自分のユーザー名が入っているとうまく表示出来ないようです。 @kimukou_26 さん、教えてくださってありがとうございます。
【2013/09/30追記】 ソースを変更いたしました。Dialogなのにdismiss()してなかったり考慮不足で申し訳ありませんでした。ソースはgithubに載せました。変更前と変更後の比較はDiffにてご覧くださいませ。
/MyExamDialogFragment/src/sakura/example/myexamdialogfragment/CommonDialogFragment.java
package sakura.example.myexamdialogfragment; import android.app.AlertDialog; import android.app.Dialog; import android.content.DialogInterface; import android.os.Bundle; import android.support.v4.app.DialogFragment; public class CommonDialogFragment extends DialogFragment { private DialogListener listener = null; public static CommonDialogFragment newInstance(String title, String message) { CommonDialogFragment frag = new CommonDialogFragment(); Bundle bundle = new Bundle(); bundle.putString("title", title); bundle.putString("message", message); frag.setArguments(bundle); return frag; } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { String title = getArguments().getString("title"); String message = getArguments().getString("message"); return new AlertDialog.Builder(getActivity()) .setIcon(R.drawable.ic_launcher) .setTitle(title) .setMessage(message) .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int whichButton) { listener.onPositiveClick(); dismiss(); } } ) .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int whichButton) { listener.onNegativeClick(); dismiss(); } } ) .create(); } /** * リスナーを追加する * * @param listener */ public void setDialogListener(DialogListener listener) { this.listener = listener; } /** * リスナーを削除する */ public void removeDialogListener() { this.listener = null; } }
/MyExamDialogFragment/src/sakura/example/myexamdialogfragment/DialogListener.java
package sakura.example.myexamdialogfragment; import java.util.EventListener; public interface DialogListener extends EventListener { /** * okボタンが押されたイベントを通知する */ public void onPositiveClick(); /** * cancelボタンが押されたイベントを通知する */ public void onNegativeClick(); }
/MyExamDialogFragment/src/sakura/example/myexamdialogfragment/Fragment01.java
package sakura.example.myexamdialogfragment; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.Button; import android.widget.Toast; public class Fragment01 extends Fragment implements OnClickListener, DialogListener { // DialogListenerを実装しておく @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if (container == null) { return null; } return inflater.inflate(R.layout.fragment01, container, false); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); Button button = (Button) getView().findViewById(R.id.button1); button.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.button1: // 以前ゴチャゴチャやってたけどもっとシンプルに書けました。考慮不足で申し訳ありません! CommonDialogFragment newFragment = CommonDialogFragment.newInstance( "title", "this is message"); newFragment.setDialogListener(this); newFragment.show(getActivity().getSupportFragmentManager(), "CommonDialogFragment"); break; default: break; } } @Override public void onPositiveClick() { Toast.makeText(getActivity(), "ok ボタンが押された", Toast.LENGTH_SHORT).show(); } @Override public void onNegativeClick() { Toast.makeText(getActivity(), "cancel ボタンが押された", Toast.LENGTH_SHORT).show(); } }
/MyExamDialogFragment/src/sakura/example/myexamdialogfragment/MainActivity.java
package sakura.example.myexamdialogfragment; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentTransaction; public class MainActivity extends FragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Fragment01 frag = new Fragment01(); FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); ft.add(R.id.main, frag, "Fragment01"); ft.commit(); } }
/MyExamDialogFragment/res/layout/activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/main" tools:context=".MainActivity" > </RelativeLayout>
/MyExamDialogFragment/res/layout/fragment01.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/root" android:layout_width="match_parent" android:layout_height="match_parent" > <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:text="ダイアログを表示する" /> </RelativeLayout>