Comments (4)
Thanks @Tolriq. We have implemented in #18
from voyager.
Hi @Tolriq. We need to use multibinding because this is the way that Dagger works with Androidx ViewModel. Hilt provides a @HitlViewModel annotation that remove all boilerplates required to use multibinding with AndroidxViewModel. This annotation doesn't works with ScreenModels. It's restricted to classes that is subclass of androidx.lifecycle.ViewModel
. So putting @HiltViewModel
on your ViewModel will generate something like that:
@Module
@InstallIn(ViewModelComponent.class)
public abstract static class BindsModule {
private BindsModule() {
}
@Binds
@IntoMap
@StringKey("cafe.adriel.voyager.sample.hiltIntegration.HiltListViewModel")
@HiltViewModelMap
public abstract ViewModel binds(HiltListViewModel vm);
}
We don't have an annotation to ScreenModel to generate multibinding to our. So we still need create our own multibinding structure manually:
// Apply `@Inject constructor` on your ScreenModel to have values injected by Hilt
class HiltListScreenModel @Inject constructor() : ScreenModel
// Create a module to have Multibinding declarations
@Module
@InstallIn(ActivityComponent::class) // Must be ActivityComponent at most. See https://dagger.dev/hilt/components
abstract class HiltModule {
@Binds
@IntoMap
@ScreenModelKey(HiltListScreenModel::class) // A key to identify this instance on Multibinding Map
abstract fun bindHiltListScreenModel(hiltListScreenModel: HiltListScreenModel): ScreenModel
// Below is a version to have support to assisted injection because there is no support by default. See https://github.com/google/dagger/issues/2287
@Binds
@IntoMap
@ScreenModelFactoryKey(HiltDetailsScreenModel.Factory::class)
abstract fun bindHiltDetailsScreenModelFactory(
hiltDetailsScreenModelFactory: HiltDetailsScreenModel.Factory
): ScreenModelFactory
}
After this all boilerplate and setup, you can get a instance of your Screen doing:
class HiltListScreen : AndroidScreen() {
@Composable
override fun Content() {
val screenModel: HiltListScreenModel = getScreenModel()
// Or if you need a version with Assisted Injection do:
val screenModel = getScreenModel<HiltDetailsScreenModel, HiltDetailsScreenModel.Factory> { factory ->
factory.create(index)
}
}
}
There is no easy way. An alternative would to create our custom @HiltScreenModel
annotation to avoid all multibinding boilerplate. But Hilt sources is out of our scope to learn and create a Kapt source generator for this purpose.
Checkout our Hilt sample to have full insight.
from voyager.
@programadorthi yes I do understand why and how the binding works.
The issue here is that if we do not use nor want to use ScreenModel we are still forced to create 2 fake things (1 screenmodel + 1 screenmodelfactory) + the fake module + the fake binding to just have the app compile.
Even when just using screen model without factory we are forced to create a fake factory + bind it to compile.
To reproduce just create an empty project add, hilt + voyager-hilt and it fails.
If there's no way to have dagger work without providing the fake one (so be optional bindings), it should either be written in big red in the doc or be provided by the voyager-hilt module.
Adding the voyager-hilt to use viewmodel and have cryptic errors and create fake module is not a nice user experience in this case.
Edit: It's actually quite simple you just need to add
@Module
@InstallIn(ActivityComponent::class)
abstract class HiltModule {
@Multibinds
abstract fun screenModelMap(): Map<Class<out ScreenModel>, ScreenModel>?
@Multibinds
abstract fun screenModelFactoryMap(): Map<Class<out ScreenModelFactory>, ScreenModelFactory>?
}
to the voyager-hilt module to have them optional.
from voyager.
Fixed on 1.0.0-beta13, feel free to reopen if the issue persists.
from voyager.
Related Issues (20)
- Compose multiplatform build failed HOT 2
- Popping navigator in background doesn't work
- navigator.pop() followed by navigator.push(screen) does not dispose the ScreenModel from the popped screen HOT 8
- Crash on Android because ScreenTransition do not inherit from Serializable HOT 5
- Double Navigation Bar Issue. HOT 1
- Can't pass the Dynamic Data using Tab Navigator
- iOS swipe to close does not work HOT 1
- Koin ScreenModel inject crash starting from 1.1.0-alpha04 HOT 1
- Screen transition broken in 1.1.0-beta02
- Can't pop root in Compose for Desktop
- [Desktop] Density is not updated on changing the window to a screen with different density
- [KMP ViewModels][Voyager][Koin] Crush if you try to navigate back
- Override the back press in each Screen in Compose Multiplatform HOT 3
- Snackbar overlapped by BottomSheet when using BottomSheetNavigator
- HorizontalPager HOT 1
- [WASM] [Font] tofu are displayed instead of the actual font HOT 1
- Android Activity Lifecycle events stop being forwarded by AndroidScreenLifecycleOwner after screen rotation
- BottomSheetNavigator - IOS Build error HOT 4
- Navigation testing
- Problem with @Transient during Screen serialization
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from voyager.