rokkonet

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

android開発 Dialogのデータを呼び出し元のActivityに渡す(独自リスナー利用)

2021 Oct. 17.
2021 Oct. 03.

出典 【Kotlin】DialogFragmentからActivityへ値を渡す - Qiita

手法

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

    public interface DialogListener{
        public fun onDialogPositive(dialog: DialogFragment)
        public fun onDialogNegative(dialog: DialogFragment)
        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 ( defaultSharedPreferences.edit()) {
            putString("myData1", myMutableMap["myData1"])
            putString("myData2", myMutableMap["myData2"])
            apply()
        }
    }

    override fun onDialogPositive(myDialog: DialogFragment) {
        // 今回、実装なし
    }

    override fun onDialogNegative(myDialog: DialogFragment) {
        // キャンセル時。今回、実装なし
    }
}


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

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

class SmbServerSettingDialogFragment: 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{
        public fun onDialogPositive(dialog: DialogFragment)
        public fun onDialogNegative(dialog: DialogFragment)
        public fun onDialogMapReceive(dialog: DialogFragment, myMutableMap: MutableMap<String, String>) //Activity側へMutableMapを渡す
    }

    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
                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
    }
}