0

I have a fragment that has a toolbar and i currently set the back button listen like this:

 with(myToolBarView) {
            (activity as AppCompatActivity).setSupportActionBar(this)
            setNavigationOnClickListener {
                requireActivity().onBackPressed()
            }
        }

but when i have other fragments this code gets repeated all the time. so i wish i could do something like this: myToolBarView by backButtonDelegate(this)

but the problem is for one, the view wont be ready until after onCreateView gets called. So i'll get null or some exception if i try to access the view before its ready. so then how i can do this?

i tried using @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) but i don't see how that will help me and also i need code called every time onoCreateView is called incase the fragment view is re-created.

update: i now [realize the lifecycleowner of a fragment works with the fragment view lifecycle][1]

so here is what i have so far:

 class BackBtnDelegate(val fragment: Fragment) {

//    operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
//        return "$thisRef, thank you for delegating '${property.name}' to me!"
//    }

    init {
        fragment.lifecycle.addObserver(object : LifecycleObserver {
            @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
            fun onDestroy() {
                with(myToolBarView) { 
                    (activity as AppCompatActivity).setSupportActionBar(this)
                    setNavigationOnClickListener {
                        requireActivity().onBackPressed()
                    }
                }
            }
        })
    }

//    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
//       // println("$value has been assigned to '${property.name}' in $thisRef.")
//    }

notice i dont even need the set or get propertty values here as they become meaningless and still i dont have a reference to myToolBarView so how can i accomplish this ? [1]: Fragment lifecycle events in LifeCycleAware Fragment

j2emanue
  • 60,549
  • 65
  • 286
  • 456

1 Answers1

1

That is not how the Delegation pattern works. Quote:

In delegation, two objects are involved in handling a request: a receiving object delegates operations to its delegate

You could create an extension function for the Fragment class:

fun Fragment.setToolbar(myToolbar: Toolbar) {
    with(myToolbar) {
    (activity as AppCompatActivity).setSupportActionBar(this)
    setNavigationOnClickListener {
        requireActivity().onBackPressed()
    }
}

Or you could have common functions in a BaseFragment and have other Fragments implement that class, but I suppose you already know that.

class BaseFragment : Fragment() {
   ...

    protected fun setToolbar(myToolbar: Toolbar) {
        with(myToolbar) {
            (activity as AppCompatActivity).setSupportActionBar(this)
            setNavigationOnClickListener {
                requireActivity().onBackPressed()
            }
        }
    }
    
    ...
}
Xid
  • 4,578
  • 2
  • 13
  • 35
  • Yes can do it from a base class but trying to avoid that for composition at this point. Delegates is what i was hoping for. Extension not a bad idea – j2emanue Sep 15 '20 at 04:02