本日も初歩的な内容ですが、Fragment
のイベントを Activity
で受け取る実装を行ったので、その方法をメモ程度に残しておきます🏃🏻♂️
それではやっていく
Fragment
側の実装は下記のようになります。重要な部分は OnboardSignUpTermsOfServiceListener
に関するところで、Activity
に通知したいイベントを Interface
として定義しています。OnboardSignUpTermsOfServiceListener
のインスタンス化は、Fragment
の onAttach()
メソッドで行います。onAttach()
メソッドは Fragment が Activity に追加される時 に呼び出され、引数として追加する Activity
がキャストされて渡されます。また、Fragment
が Activity
から関連付けられなくなった場合にイベントが通知され続けるのを防ぐため onDetach()
でリスナーを破棄しています。
class OnboardSignUpTermsOfServiceFragment : Fragment() { interface OnboardSignUpTermsOfServiceListener { fun onClickNext() } private var _binding: FragmentOnboardSignUpTermsOfServiceBinding? = null private val binding get() = _binding!! private var listener: OnboardSignUpTermsOfServiceListener? = null override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { _binding = FragmentOnboardSignUpTermsOfServiceBinding.inflate(inflater, container, false) binding.nextButton.setOnClickListener { onClickNext(it) } return binding.root } override fun onDestroyView() { super.onDestroyView() _binding = null } override fun onAttach(context: Context) { super.onAttach(context) listener = context as? OnboardSignUpTermsOfServiceListener if (listener == null) { throw ClassCastException("$context must implement OnboardSignUpTermsOfServiceListener") } } override fun onDetach() { super.onDetach() listener = null } fun onClickNext(view: View) { listener?.onClickNext() } }
最後に Activity
側で Interface
に準拠することでイベントを受け取れるようになります。
class OnboardSignUpActivity : AppCompatActivity(), OnboardSignUpTermsOfServiceFragment.OnboardSignUpTermsOfServiceListener { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_onboard_sign_up) } // MARK: OnboardSignUpTermsOfServiceListener override fun onClickNext() { // TODO: Handle events. } }
参考
- https://developer.android.com/guide/components/fragments?hl=ja#CommunicatingWithActivity
- https://qiita.com/Reyurnible/items/d6397f5fbb03ee4fb93b