Skip to content

Instantly share code, notes, and snippets.

@igorwojda
Created August 9, 2019 21:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save igorwojda/63c2ff2e138d55ceabc4f597b8938984 to your computer and use it in GitHub Desktop.
Save igorwojda/63c2ff2e138d55ceabc4f597b8938984 to your computer and use it in GitHub Desktop.
// Can be used as generic method to retrieve NavArgs? in the BaseViewModel
// usage val viewModel by navArgsReflection()
class NavArgsReflectionLazy<Args : NavArgs?>(
private val navArgsClass: KClass<out Fragment>,
private val arguments: () -> Bundle?
) :
ReadOnlyProperty<Any?, Args?> {
private var navArgs: NavArgsLazy<*>? = null
override fun getValue(thisRef: Any?, property: KProperty<*>): Args? {
if (navArgs == null) {
val localArguments = arguments.invoke() ?: return null
val className = "${navArgsClass.java.canonicalName}Args"
// Let's check if Args class actually exists
val navArgsClass = requireNotNull(getArgNavClass(className)) {
"Arguments where passed to a fragment, but corresponding argument class $className does not exist. Arguments: $arguments"
}
navArgs = NavArgsLazy(navArgsClass) { localArguments }
}
@Suppress("UNCHECKED_CAST")
return navArgs?.value as Args
}
private fun getArgNavClass(className: String): KClass<NavArgs>? = try {
@Suppress("UNCHECKED_CAST")
Class.forName(className).kotlin as KClass<NavArgs>
} catch (e: ClassNotFoundException) {
null
}
}
@MainThread
fun Fragment.navArgsReflection() = NavArgsReflectionLazy<NavArgs>(this::class) { arguments }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment