Android

ActivityとFragmentの両方で使えるDialogFragmentの書き方

More than 3 years have passed since last update.


概要

Androidアプリでダイアログを実装するには、今はDialogFragmentを使うことがほぼ必須になってます。通知的なダイアログなら実装も楽ですが、だいたいはダイアログに対して何かの情報を渡して何かの情報をもらうようなケースが多いと思います。

加えてダイアログの呼び出し元もActivityだったりFragmentだったりいろんな状況に対応させることが増えてきたので、タイトルにあるようなダイアログをコネコネしてみました。

まとめると以下のような要件になります。


  • Activityから呼び出してコールバックを受けられる

  • Fragmentから呼び出してコールバックを受けられる

  • ダイアログの生成に必要なデータを渡せる


サンプルコード

import android.app.Activity;

import android.app.Dialog;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.view.View;

public class CustomDialog extends DialogFragment {

public interface OnCustomDialogListener {
public void onCustomDialogClick(int which);
}

private OnCustomDialogListener mListener;

public static CustomDialog newInstance(Bundle bundle) {
CustomDialog instance = new CustomDialog();
instance.setArguments(bundle);
return instance;
}

public static CustomDialog newInstance(Bundle bundle, Fragment fragment) {
CustomDialog instance = new CustomDialog();
instance.setArguments(bundle);
instance.setTargetFragment(fragment, 0);
return instance;
}

@Override
public void onAttach(Activity activity) {
super.onAttach(activity);

Fragment targetFragment = this.getTargetFragment();
try {
mListener = (targetFragment != null) ? (OnCustomDialogListener) targetFragment : (OnCustomDialogListener) activity;
}
catch (ClassCastException e) {
throw new ClassCastException("Don't implement OnCustomDialogListener.");
}
}

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Bundle bundle = this.getArguments();
View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_custom, null);

return new AlertDialog.Builder(getActivity())
.setTitle("サンプル")
.setView(view)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int witch) {
mListener.onCustomDialogClick(int witch);
}
})
.create();
}
}


補足



  • onCreateDialog()の中は適当です。どういうダイアログにするのかによりますので、適時書き換える箇所になります。

  • 呼び出し元のFragmentののインスタンスは、必ずsetTargetFragmentしたものを使います。インスタンス変数などに控えたものだと、自動再生成したときなどに正しいインスタンスが取れません。