以前紹介したダイアログでは表示中に画面を回転するとエラーが発生します。
今回はDialogFragmentを継承したMyDialogを作成して
回転してもエラーが出ないインプットダイアログを作成し、使ってみます。
ボタンを押すとテキストボックス付きのダイアログが表示され、
テキストを入力してOKを押すと
画面中央のテキストボックスに入力したテキストを表示するアプリになっています。
公式サイトのダイアログ
package com.example.samplerotationabledialog
import android.app.AlertDialog
import android.app.Dialog
import android.content.Context
import android.os.Bundle
import android.widget.EditText
import androidx.fragment.app.DialogFragment
private const val KEY_MESSAGE_BOX_TEXT = "message box text"
class MyDialog : DialogFragment() {
interface MyDialogListener { // *1
fun onMyDialogPositiveClicked(dialog: MyDialog)
fun onMyDialogNegativeClicked(dialog: MyDialog)
}
private lateinit var listener: MyDialogListener
var inputText = "" // *2
private lateinit var edtText: EditText // *3
override fun onAttach(context: Context) { // *4
super.onAttach(context)
try {
listener = context as MyDialogListener
} catch (e: ClassCastException) {
throw ClassCastException((context.toString() +
" must implement MyDialogListener."))
}
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
edtText = EditText(context)
if (savedInstanceState != null) {
edtText.setText(savedInstanceState.getString(KEY_MESSAGE_BOX_TEXT)) // *7
}
val builder = AlertDialog.Builder(activity)
.setTitle("title")
.setMessage("message")
.setView(edtText)
.setPositiveButton("ok") {_, _ ->
inputText = edtText.text.toString()
listener.onMyDialogPositiveClicked(this)
}
.setNegativeButton("cancel") {_, _ ->
listener.onMyDialogNegativeClicked(this)
}
return builder.create() // *5
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putString(KEY_MESSAGE_BOX_TEXT, edtText.text.toString()) // *6
}
}
*1 Activityでダイアログのイベントを受け取るためにリスナーを定義します。
*2 インプットダイアログなので入力された文字列を保管し、Activityで取り出すためにここに宣言しました。
*3 onSaveInstanceStateで参照したいので、インプットダイアログ内で使用するテキストボックスをここで定義します。
*4 onAttachはonCreateよりも前に発生し、FragmentとActivityが関連付けられたときに呼ばれる。listenerにcontextを渡している。
*5 .show()ではなく.create()なので要注意。Activity側でshow()します。
*6 画面が回転する直前にテキストボックス内の文字列を保存しています。
*7 画面が回転してダイアログが再作成されたときに、保存していた文字列をテキストボックスにセットしています。
package com.example.samplerotationabledialog
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.example.samplerotationabledialog.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity(), MyDialog.MyDialogListener { // *1
private lateinit var binding: ActivityMainBinding // *0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.btnText.setOnClickListener {
val dialog = MyDialog()
dialog.show(supportFragmentManager, "MyDialog")
}
}
override fun onMyDialogPositiveClicked(dialog: MyDialog) { // *2
binding.txvSample.text = dialog.inputText
}
override fun onMyDialogNegativeClicked(dialog: MyDialog) { // *3
binding.txvSample.text = "cancel clicked."
}
}
*0 bindingの使い方はこちら
*1 MyDialogのMyDialogListenerを継承します。
*2 ダイアログでOKをクリックしたときの処理を実装します。
*3 ダイアログでキャンセルをクリックしたときの処理を実装します。