rokkonet

PC・Androidソフトウェア・アプリの開発・使い方に関するメモ

android開発 ダイアログから呼び出し元に値を渡す(独自リスナー利用)

2022 Apr. 29.
2022 Mar. 03.
2021 Oct. 03.

出典 【Kotlin】DialogFragmentからActivityへ値を渡す - Qiita
参考 android開発 ダイアログから呼び出し元に値を渡す - rokkonet

手法

ダイアログクラスに、呼び出し元Activityにデータを渡す抽象メソッドを持つインターフェースを組み込む
class MyDialogFragment: DialogFragment()  {

    public interface DialogListener{
        public fun onDialogMapReceive(dialog: DialogFragment, myMutableMap: MutableMap<String, String>) //Activity側へMutableMapを渡す
    }
}


呼び出し元のActivityにインターフェースを実装する

ダイアログのOKボタンが押された時に実行する処理を、インターフェースの実装メソッドとして記述する。

class MainActivity : AppCompatActivity(), MyDialogFragment.DialogListener {

    override fun onDialogMapReceive(myDialog: DialogFragment, myMutableMap: MutableMap<String, String>) {
        //myDialogからの値を受け取り、defaultSharedPreferencesに保存する
        with ( getDefaultSharedPreferences().edit()) {
            putString("myData1", myMutableMap["myData1"])
            putString("myData2", myMutableMap["myData2"])
            apply()
        }
    }


呼び出し元Activityに実装したメソッドをダイアログクラスから呼び出せるようにする

ダイアログクラスの生成時に呼ばれるonAttach()内で、インターフェースコンテクストを取得し変数にセットする。
 listener = context as DialogListener

class MyDialogFragmen: DialogFragment()  {

    var listener:DialogListener? = null

    // DialogListenerインターフェースコンテクストをlistenerにセットする
    //   MainActivityで実装したDialogListenerインターフェースのメソッドを利用できるようになる
    override fun onAttach(context: Context) {
        super.onAttach(context)
        try {
            listener = context as DialogListener
        }catch (e: Exception){
            Log.e("MyApp","CANNOT FIND LISTENER")
        }
    }

    override fun onDetach() {
        super.onDetach()
        listener = null
    }
}


ダイアログクラス内の、呼び出し元Activityにデータを渡すタイミングのところで、呼び出し元Activityに記述した実装メソッドを実行する
class MyDialogFragment: DialogFragment()  {

    public interface DialogListener{
        //Activity側へMutableMapを渡すための抽象メソッド
        public fun onDialogMapReceive(dialog: DialogFragment, myMutableMap: MutableMap<String, String>)
    }

    var listener:DialogListener? = null

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        var mySettings: MutableMap<String, String> = mutableMapOf(  // 受け渡しする値を格納する変数
            "data1" to "",
            "data2" to ""
        )

        val builder = AlertDialog.Builder(activity)
        val inflater = requireActivity().layoutInflater
        val mySettingView = inflater.inflate(R.layout.dialog_my_setting, null)
        builder.setView(mySettingView)
            .setTitle("My Setting")
            .setPositiveButton("OK") { dialog, id ->
                    mySettings.put(  // 受け渡しする値を変数にセット
                        "data1",
                        mySettingView.findViewById<EditText>(R.id.data1).text.toString()
                    )
                    mySettings.put(
                        "data2",
                        mySettingView.findViewById<EditText>(R.id.data2).text.toString()
                    )

                // pass data to the Activity having called this dialog
                // 呼び出し元Activityに記述された実装内容が実行される。
                // それにより、呼び出し元Activityでデータを扱える
                listener?.onDialogMapReceive(this, mySettings)

            }
            .setNegativeButton("Cancel") { dialog, id ->
                // nothing is done
            }
        return builder.create()
    }

    // DialogListenerインターフェースをlistenerにセットする
    //   MainActivityで実装したDialogListenerインターフェースのメソッドを利用できるようになる
    override fun onAttach(context: Context) {
        super.onAttach(context)
        try {
            listener = context as DialogListener
        }catch (e: Exception){
            Log.e("MyApp","CANNOT FIND LISTENER")
        }
    }

    override fun onDetach() {
        super.onDetach()
        listener = null
    }
}