はじめに
AndroidのAlertDialogを使っていると、messageのViewを取得したいことがあります。
検索すると、AlertDialogをそのまま使っているパターンで、messageのTextViewを取得する方法が出てきます。
こんな感じで↓
val builder = AlertDialog.Builder(context).apply {
setMessage(message)
}
val dialog = builder.show()
val messageView = dialog.findViewById<TextView>(android.R.id.message)
しかし、ダイアログによるとAlertDialogはDialogFragmentで包んであげることが推奨されており、AlertDialogをそのままshow()する場面はあまり多くないと思います(少なくとも私の所属するプロジェクトでは)。
サンプルは以下の通りです(ダイアログから抜粋)。
class FireMissilesDialogFragment : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle): Dialog {
return activity?.let {
// Use the Builder class for convenient dialog construction
val builder = AlertDialog.Builder(it)
builder.setMessage(R.string.dialog_fire_missiles)
.setPositiveButton(R.string.fire,
DialogInterface.OnClickListener { dialog, id ->
// FIRE ZE MISSILES!
})
.setNegativeButton(R.string.cancel,
DialogInterface.OnClickListener { dialog, id ->
// User cancelled the dialog
})
// Create the AlertDialog object and return it
builder.create()
} ?: throw IllegalStateException("Activity cannot be null")
}
}
問題点
この場合、どうやってmessageのTextViewを取得するか?
DialogFragmentのshowメソッドはvoidなので、冒頭で述べたような方法でshow後にAlertDialogを取得することはできません。DialogFragmentのインスタンスからgetDialog()して、findViewByIdしようとしてもgetDialogがnullを返すようです。
では、どうするか。
結論
DialogFragmentのonStart
でfindViewByIdする。
class MyDialog: DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return activity?.let {
AlertDialog
.Builder(it)
.setMessage("メッセージ")
.setPositiveButton("OK", null)
.create()
} ?: throw IllegalStateException("Activity cannot be null")
}
override fun onStart() {
super.onStart()
val textView = (dialog as? AlertDialog)?.findViewById<TextView>(android.R.id.message)
// 色を変える
textView?.setTextColor(Color.BLUE)
// 文字サイズを変える
textView?.textSize = 40f
}
}