Skip to content

Instantly share code, notes, and snippets.

@msymt
Last active September 12, 2020 05:26
Show Gist options
  • Save msymt/adacf1a6a11d6c33cb8be34fbe861bf9 to your computer and use it in GitHub Desktop.
Save msymt/adacf1a6a11d6c33cb8be34fbe861bf9 to your computer and use it in GitHub Desktop.
[Android]fragmentからDialogfragmentを呼び出して、fragment側でDialogfragmentの結果を受け取る方法

はじめに

以下のサイトを参考にし、自分用にメモと実装例を残しました。詳しくは以下のサイトをご覧ください。

https://tech.mokelab.com/android/Fragment/dialog.html

https://tech.mokelab.com/android/Fragment/result.html

注意

ここで紹介するのは、2020年9月10日の現時点で、安定な1.2.5でのやり方です。

fragment1.3.0-alpha04からは別の方法がありますので、下の公式ドキュメント参考にしてください。

https://developer.android.com/training/basics/fragments/pass-data-between

本題

ここでのDialogFragmentは、よくある2択を選択するダイアログを表示させ、文字列を呼び出し元のfragmentに返すという機能とします。

プログラミング言語はKotlinを採用しております。

呼び出し元Fragment(FirstFragment)

呼び出すFragmentオブジェクトを生成

// 呼び出すFragmentオブジェクトを生成(CUSTOM_DIALOG_CALLはこちらで定義)
val customDialogFragmet = CustomDialogFragmet.newInstance(this@FirstFragment, CUSTOM_DIALOG_CALL)
CustomDialogFragmet.show(parentFragmentManager, "CustomDialogFragmet")

呼び出し先からの結果をonActivityResultで受け取る

// customFragmentから結果を受け取る
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
  if (requestCode == CUSTOM_DIALOG_CALL && resultCode == Activity.RESULT_OK) {
    if (data != null) {
      // やりたいこと
      val text = data?.getStringExtra(Intent.EXTRA_TEXT)
      if (text != null) Log.d("debug", text)
    }
  }
}

呼び出し先Fragment(CustomDialogFragmet)

setTargetFragmentで呼び出し元のfragmentオブジェクトとrequestCodeをセット

companion object {
        // set: fragment object, requestCode
        @JvmStatic
        fun newInstance(fragment: Fragment, requestCode: Int): CustomFragment {
            val dialog = CustomDialogFragmet()
            dialog.setTargetFragment(fragment, requestCode)

            val args = Bundle()
            fragment.arguments = args

            return  dialog
        }
    }

呼び出された側で、結果を伝えるためにtargetFragmentで、呼び出し元のfragmentオブジェクトを取得

putExtraで渡したい値をセット

private fun onSubmit(inputText: String) {
        if(targetFragment == null) return
        val data = Intent()
        data.putExtra(Intent.EXTRA_TEXT, inputText)
        targetFragment!!.onActivityResult(targetRequestCode, Activity.RESULT_OK, data)
    }

CustomDialogFragmentの全文

class CustomFragment: DialogFragment() {

    companion object {
        // set: fragment object, requestCode
        @JvmStatic
        fun newInstance(fragment: Fragment, requestCode: Int): CustomFragment {
            val dialog = CustomFragment()
            dialog.setTargetFragment(fragment, requestCode)

            val args = Bundle()
            fragment.arguments = args

            return  dialog
        }
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        if(activity == null) return super.onCreateDialog(savedInstanceState)

        val dialog: AlertDialog.Builder = AlertDialog.Builder(activity)
        dialog.setTitle("2択")

        dialog.setPositiveButton("はい", onPositiveClick())
        dialog.setNegativeButton("いいえ", onNegativeClick())
        return dialog.create()
    }

    override fun onPause() {
        super.onPause()
        dismiss() // メモリリーク対策
    }

    private inner class onPositiveClick(): DialogInterface.OnClickListener {
        override fun onClick(dialog: DialogInterface?, which: Int) {
            onSubmit(”はい”)
        }
    }

    private inner class onNegativeClick(): DialogInterface.OnClickListener {
        override fun onClick(dialog: DialogInterface?, which: Int) {
            onSubmit("いいえ")
        }
    }

    private fun onSubmit(inputText: String) {
        if(targetFragment == null) return
        val data = Intent()
        // 呼び出し元に渡したいデータ
        data.putExtra(Intent.EXTRA_TEXT, inputText)
        targetFragment!!.onActivityResult(targetRequestCode, Activity.RESULT_OK, data)
    }
}

おわりに

Kotlin、Android共に初心者ながら書いてみました。

Kotlinに早く慣れたい今日この頃

早く安定版の更新来ないかな

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment