Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds override method for onViewCreated. #504

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open

Adds override method for onViewCreated. #504

wants to merge 1 commit into from

Conversation

ghost
Copy link

@ghost ghost commented Nov 20, 2018

No description provided.

@EricKuck
Copy link
Member

What's the use case for having a method like this?

@ghost
Copy link
Author

ghost commented Nov 22, 2018

I can speak about a personal use case, say I want to tell my presenter to load some data when the view is created (which fetches from a local data source) and then display that data.

Currently to do this, i'd make the call to presenter before the onCreateView returns. Then once it comes back in my Controller have something like view?.customView?.bind(data) view being the View reference held by Controller, but if onCreateView has not returned that reference will still be null.

Maybe is a bit of an edge case, but IMO would be nice to be able to kick off work with the assurance the view held by Controller has definitely been assigned.

@inorichi
Copy link
Contributor

It happened to me too with kotlin synthetic properties, but you can workaround this with a custom BaseController too:

abstract class BaseController(bundle: Bundle? = null) : RestoreViewOnCreateController(bundle) {

    init {
        addLifecycleListener(object : LifecycleListener() {
            override fun postCreateView(controller: Controller, view: View) {
                onViewCreated(view)
            }
        })
    }

    open fun onViewCreated(view: View) { }

}

@dimsuz
Copy link
Contributor

dimsuz commented Nov 23, 2018

I did this without adding lifecycle listener:

abstract class BaseController : Controller {

  constructor()
  constructor(args: Bundle) : super(args)

  final override fun onCreateView(inflater: LayoutInflater, container: ViewGroup): View {
    val rootView = inflater.inflate(getViewLayout(), container, false)
    initializeView(rootView)
    return rootView
  }

  abstract fun initializeView(rootView: View)
}

But with this implementation initializeView will have a view which is not yet attached to the view hierarchy, if this is important, than @inorichi solution is probably a better one.

@inorichi
Copy link
Contributor

That wouldn't work with the LayoutContainer interface from the synthetic properties because it uses getView(). But you could also store locally rootView and set it to null in onDestroyView.

Here's the full controller implementation I added in another issue.

@ghost
Copy link
Author

ghost commented Nov 23, 2018

I have actually used both solutions in the past, prefer the one from @inorichi as you can be sure the view held by the Controller has been set.

Although ideally I would prefer to remove the need for a workaround base class altogether.

@dimsuz
Copy link
Contributor

dimsuz commented Nov 23, 2018

That wouldn't work with the LayoutContainer interface

Yep, I omitted those parts for brevity, but here's the full code which I use for working with synthetic properties:

abstract class BaseController : Controller, LayoutContainer {
  private var bindPropsRootView: View? = null

  constructor()
  constructor(args: Bundle) : super(args)

  final override fun onCreateView(inflater: LayoutInflater, container: ViewGroup): View {
    val rootView = inflater.inflate(getViewLayout(), container, false)
    bindPropsRootView = rootView
    // initialization can happen only after bindPropsRootView is assigned, this is required for view cache to work
    initializeView(rootView)
    return rootView
  }

  @LayoutRes
  abstract fun getViewLayout(): Int

  abstract fun initializeView(rootView: View)
  protected open fun destroyView(view: View) {}

  override val containerView: View? get() = bindPropsRootView

  final override fun onDestroyView(view: View) {
    clearFindViewByIdCache()
    bindPropsRootView = null
    super.onDestroyView(view)
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants