material-components-android-codelabs is a git repo of demo code for material components. In the 102-starter branch of this repo, in LoginFragment.kt, there's this bit of code
(actvity as NavigationHost).navigateTo(ProductGridFragment(),false)
In the import statements, nothing in there seems to indicate where activity
comes from and using android studio to find any declaration goes to a function with the signature public final FragmentActivity getActivity()
. How is activity
set and brought into the scope of the fragment?
CodePudding user response:
getActivity()
is a method on Fragment
instances, and Kotlin allows you to access Java-style setters and getters as though they're properties:
// getters
val newThing = stuff.getThing()
val newThing = stuff.thing
// setters
stuff.setThing(newThing)
stuff.thing = newThing
// boolean setters
dog.setGood(true)
dog.isGood = true
// boolean getters
val goodBoy = dog.isGood()
val goodBoy = dog.isGood
note that the property versions look the same whether you're getting or setting, you're just reading and writing to a single "property". Under the hood, it's making the call to the relevant function.
CodePudding user response:
Fragment
has a function: final public FragmentActivity getActivity()
-> since you're in the scope of a fragment
, and the function is in the fragment
scope, too, you don't need any import
To be able to use this activity reference, your fragment needs to be attached to an activity. => This should happen somewhere around onAttatch()
.
Last tip: when you're in a lifecycle where you're sure you have a backing activity, you can use requireActivity()
to avoid unnecessary null-checks
CodePudding user response:
Kotlin allows you to get and set properties directly without calling the method. E.g. instead of calling getActivity
, you can just use activity
. So (actvity as NavigationHost)
actually translates to (getActivity() as NavigationHost)
Check the Kotlin reference here. Quote from the linked documentation:
To use a property, simply refer to it by its name