FragmentクラスのonAttachを用いたコールバックの実装方法を説明しています。この方法でFragmentからActivity側のメソッドを実行することが出来ます。また、DialogFragmentでも同様に実装可能です。
概要
FragmentからActivity(呼び出し元)のメソッドを実行します。
初めに以下の準備が必要となります。
- Fragment側に実行したいメソッドを定義したインタフェースを作成する
- Fragment側のonAtatchをoverrideして、インタフェースで定義したメソッドをセットする
- Activity側でインタフェースで定義したメソッドをoverrideして実装する
ここまで出来たら、Fragmentの中の必要なタイミングで実行します。
実装例
レイアウト
activity_main.xml
メインアクテビティのレイアウトです。
上から順番にfragment、TextView、Buttonの3つです。
- fragment
fragmentの領域、fragment内のボタンを押すとTextViewを更新する - TextView
コールバックの動作確認する - Button
dialogを表示する、dialog内のボタンを押すとTextViewを更新する

fragment_sample.xml
フラグメントのレイアウトです。
ボタンを押すと、メインアクテビティのテキストの表示内容を更新します。

dialog_sample.xml
ダイアログのレイアウトです。
Positiveボタン(OKボタン)を押すと、メインアクテビティのテキストの表示内容を更新します。

実装方法
SampleFragment.kt
実装のポイントは以下の点です。
- クラス内で参照できるようにListenerの変数を定義
- Interfaceでメソッドを定義
→MainActivityでoverrideする - onAttachでListenerの変数にセット
→MainActivityでoverrideしたListenerをセットする - ボタンを押したときにInterfaceで定義したメソッドを実行
class SampleFragment : Fragment() {
//Listenerをセットする変数
private lateinit var listener: CallbackListener
//実行するメソッドを定義したInterface
interface CallbackListener {
fun updateButtonClickFromFragment()
}
//この中でListenerにセットする
override fun onAttach(context: Context) {
super.onAttach(context)
try {
//MainActivity(呼び出し元)をListenerに変換する
val mainActivity: MainActivity = activity as MainActivity
listener = mainActivity
} catch (e: ClassCastException) {
throw ClassCastException((context.toString() +
" must implement NoticeDialogListener"))
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val root: View = inflater.inflate(R.layout.fragment_sample, container, false)
//更新用ボタン
val buttonUpdate: Button = root.findViewById(R.id.buttonUpdate)
buttonUpdate.setOnClickListener {
listener.updateButtonClickFromFragment()
}
return root
}
}
SampleDialogFragment.kt
Fragmentと実装方法は変わりありません。
class SampleDialogFragment : DialogFragment() {
//Listenerをセットする変数
private lateinit var listener: CallbackListener
//実行するメソッドを定義したInterface
interface CallbackListener {
fun updateButtonClickFromFragmentDialog()
}
//この中でListenerにセットする
override fun onAttach(context: Context) {
super.onAttach(context)
try {
//MainActivity(呼び出し元)をListenerに変換する
val mainActivity: MainActivity = activity as MainActivity
listener = mainActivity
} catch (e: ClassCastException) {
throw ClassCastException((context.toString() +
" must implement NoticeDialogListener"))
}
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return activity?.let {
val builder = AlertDialog.Builder(it)
val inflater = requireActivity().layoutInflater;
val root = inflater.inflate(R.layout.dialog_sample, null)
//viewにレイアウトをセット
builder.setView(root)
.setPositiveButton("OK",
DialogInterface.OnClickListener { dialog, id ->
listener.updateButtonClickFromFragmentDialog()
})
.setNegativeButton("CANCEL",
DialogInterface.OnClickListener { dialog, id ->
getDialog()?.cancel()
})
builder.create()
} ?: throw IllegalStateException("Activity cannot be null")
}
}
MainActivity.kt
Fragmentのインタフェースで定義したメソッドをoverrideして実装しています。
- updateButtonClickFromFragment
Fragmentで定義したメソッド - updateButtonClickFromFragmentDialog
FragmentDialogで定義したメソッド
//FragmentのListenerを継承する
class MainActivity : AppCompatActivity()
, SampleFragment.CallbackListener
, SampleDialogFragment.CallbackListener {
//Fragmentのボタンを押したときの処理
override fun updateButtonClickFromFragment() {
val textView: TextView = findViewById(R.id.textView)
textView.text = "Update From Fragment!!"
}
//FragmentDialogのボタンを押したときの処理
override fun updateButtonClickFromFragmentDialog() {
val textView: TextView = findViewById(R.id.textView)
textView.text = "Update From FragmentDialog!!"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//Dialog表示ボタン
val buttonShowDialog: Button = findViewById(R.id.buttonShowDialog)
buttonShowDialog.setOnClickListener {
val newFragment = SampleDialogFragment()
newFragment.show(supportFragmentManager, "test")
}
}
}
実行結果
アプリ起動時

Fragmentのボタンを押したとき
Fragment内のボタン(画面上部)を押すと、中央のテキストの表示が変わっています。FragmentからActivityの更新が行えていることが分かります。

DialogFgmentのボタンを押したとき
DialogFragment内のOKボタンを押すと、中央のテキストの表示が変わっています。DialogFragmentからActivityの更新が行えていることが分かります。

まとめ
FragmentクラスのonAttachを用いたコールバックの実装方法を説明しました。
説明した実装方法を用いると、FragmentからActivity側のメソッドを実行することが出来ます。また、DialogFragmentでも同様に実装可能です。
要点は以下の通りです。
- Fragment側のInterfaceでメソッドを定義する
- Activity側でメソッドを実装する
- onAttachで実装したメソッドを取得して、Fragment側で実行する
Fragment(遷移先)からActivity(呼び出し元)を操作したい場面で活用しましょう。

