- class LoginFragment : Fragment() {
- private var _binding: FragmentLoginBinding? = null
- private val binding: FragmentLoginBinding
- get() = _binding!!
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View {
- _binding = FragmentLoginBinding.inflate(inflater, container, false)
- return binding.root
- }
- override fun onDestroyView() {
- super.onDestroyView()
- _binding = null
- }
- }
「Fragment.viewLifecycleOwnerLiveData で LiveData<LifecycleOwner?> が取れます」で紹介した viewLifecycleOwnerLiveData を使うと、onDestroyView() で null を代入する処理を自動でやってくれる ViewBinding 用の property delegates を作ることができます。
https://medium.com/@Zhuinden/simple-one-liner-viewbinding-in-fragments-and-activities-with-kotlin-961430c6c07c を参考に変更を加えています。
- class FragmentViewBindingDelegate<T : ViewBinding>(
- val fragment: Fragment,
- val viewBindingFactory: (View) -> T
- ) : ReadOnlyProperty<Fragment, T> {
- private var binding: T? = null
- private val viewLifecycleOwnerObserver = Observer<LifecycleOwner?> {
- if (it == null) {
- binding = null
- }
- }
- private val observer = object : DefaultLifecycleObserver {
- override fun onCreate(owner: LifecycleOwner) {
- fragment.viewLifecycleOwnerLiveData.observeForever(viewLifecycleOwnerObserver)
- }
- override fun onDestroy(owner: LifecycleOwner) {
- fragment.viewLifecycleOwnerLiveData.removeObserver(viewLifecycleOwnerObserver)
- fragment.lifecycle.removeObserver(this)
- }
- }
- init {
- if (fragment.lifecycle.currentState != Lifecycle.State.DESTROYED) {
- fragment.lifecycle.addObserver(observer)
- }
- }
- override fun getValue(thisRef: Fragment, property: KProperty<*>): T {
- val binding = binding
- if (binding != null) {
- return binding
- }
- val view = thisRef.view
- checkNotNull(view) {
- "Should get bindings when the view is not null."
- }
- return viewBindingFactory(view).also { this.binding = it }
- }
- }
- fun <T : ViewBinding> Fragment.viewBinding(viewBindingFactory: (View) -> T) =
- FragmentViewBindingDelegate(this, viewBindingFactory)
- class LoginFragment : Fragment() {
- private val binding by viewBinding(FragmentLoginBinding::bind)
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View {
- return inflater.inflate(R.layout.fragment_login, container, false)
- }
- }
0 件のコメント:
コメントを投稿