Problem
I don't think it's necessary to add something to ViewScope<T>
every time we need to use some common values. Also, there should be a way to provide instances as DI does.
Solution
I think in this case we should divide types of instances we provide. So, I propose next types of instances:
- static โ initializes on application init and never changes (for example,
ApplicationInstance
)
- local โ initializes in specific scope (for example,
LocalContext
that is unique for each view)
- mutable โ can be changed while program runs (for example,
AccountInstance
where account can change due to log in / log out)
Providing instances
To provide instance, we use provider
function, for example:
class Account(val name: String)
val AccountInstance = instance<Account?> { error("Not yet initialized") }
internal fun ViewGroupScope<*>.AppView() {
provider(AccountInstance provides Account("test")) {
AccountView()
}
}
Getting instances
To get instance, we just call corresponding instance in ViewScope<T>
:
internal fun ViewGroupScope<*>.AccountView() {
frameLayout(frameLayoutParams().maxSize()) {
AccountInstance.state.constructOnEach { account ->
if (account != null) {
textView {
text("Hello, ${account.name}!")
}
} else {
button(layoutParams().width(64.dp)) {
text("Sign in")
gravity(Gravity.CENTER)
}
}
}
}
}
It's important to have ViewScope<T>
, because it stores instanceProvider: InstanceProvder
.