2015年2月16日月曜日

【Android】DialogFragmentを継承したダイアログの作り方

今回はダイアログの作成方法を書いていきます。


以前はダイアログを作成するのはなかなかコードの量が多く大変だったのですが、
DialogFragmentにより簡単に作成できるようになりました。 
DialogFragmentはAPIレベル11から追加されています。

Android Studioで自動生成されるFragment(Blank)のテンプレートを利用して ダイアログを作成すると簡単に作成できます。

public class MessageDialogFragment extends DialogFragment {

    private static final String TITLE = "title";
    private static final String MESSAGE = "message";

    private String mTitle;
    private String mMessage;

    //OKボタンが押されたことを通知するリスナー
    private OnOkButtonClickedListener mListener;

    public static MessageDialogFragment newInstance(String title, String message) {
        MessageDialogFragment fragment = new MessageDialogFragment();
        Bundle args = new Bundle();
        args.putString(TITLE, title);
        args.putString(MESSAGE, message);
        fragment.setArguments(args);
        return fragment;
    }

    public MessageDialogFragment() {
        //何も書かない
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mTitle = getArguments().getString(TITLE);
            mMessage = getArguments().getString(MESSAGE);
        }

        //ダイアログの作成
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle(mTitle)
                .setMessage(mMessage)
                .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        mListener.onOkButtonClicked();
                    }
                });
        return builder.create();
    }

    @Override
    public void onAttach(Activity activity) {
        //リスナーのセット
        super.onAttach(activity);
        try {
            mListener = (OnOkButtonClickedListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnOkButtonListener");
        }
    }

    @Override
    public void onDetach() {
        //リスナーの削除
        super.onDetach();
        mListener = null;
    }

    public interface OnOkButtonClickedListener {
        public void onOkButtonClicked();
    }
}

DialogFragmentで注意が必要なのは、onCreateViewは必ず消して下さい。
残っているとエラーが発生してアプリが強制終了します。
ダイアログを表示させるActivityは以下のようにします。

public class MainActivity extends ActionBarActivity implements View.OnClickListener, MessageDialogFragment.OnOkButtonClickedListener{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final Button btnPush = (Button)findViewById(R.id.btn_push);
        btnPush.setOnClickListener(this);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onClick(View v) {
        MessageDialogFragment dialog = MessageDialogFragment.newInstance("タイトル", "メッセージ");
        dialog.show(getSupportFragmentManager(), "dialog");
    }

    @Override
    public void onOkButtonClicked() {
        //今回は何もしない
    }
}

この時、注意が必要なのは、onAttachでactivityをキャストしているので
必ずFragmentで作成したinterfaceをimplementsして下さい。

今回はボタンクリックでダイアログを表示させるので、
onClickの中でnewInstanceした後、dialog.showで表示します。
以上です。