Koin sharedViewModel with SavedStateHandle - android

I have single activity application and number of fragments. Some of these fragments are using my viewmodel, typically like this:
private val myViewModel: MyViewModel by sharedViewModel()
What if I want to have the model both shared and keep its state with SavedStateHandle? I cannot figure out if this is supported and if so, how it needs to be used (declaring viewmodel as stateViewModel in hosting activity is not working).

Update: as koin 2.1.6 is around, they introduced org.koin.androidx.viewmodel.ext.android.stateSharedViewModel that you can use in your fragments.
Ok after an hour of digging Koin samples and figuring out a few gotchas:
Assuming your view model is something similar to this:
class SavedStateViewModel(val handle: SavedStateHandle, val service: SimpleService)
...and your DI looks like this:
viewModel { (handle: SavedStateHandle) -> SavedStateViewModel(handle, get()) }
Your shared state view model can be consumed in your fragments like this:
val sharedSaved: SavedStateViewModel by sharedViewModel()
(important!) You need this declaration in your activity:
lateinit var savedVm: SavedStateViewModel
(important) You need to call this right after super.onCreate(savedInstanceState) in your activity:
savedVm = getStateViewModel()
It is important not to use lazy version for the above (stateViewModel).

Related

How to inject dependency in composable using dagger hilt

Maybe I'm blind but I can't find anything about injecting a dependency that needs parameters in side a composable using dagger hilt.
Lets say my ViewModel looks something like this:
class MyViewModel #AssistedInject constructor(#Assisted myValue: Int) : ViewModel() {
...
}
and I've got a factory interface like this:
#AssistedFactory
interface MyViewModelAssistedFactory {
fun create(myValue: Int): MyViewModel
}
how can I inject that dependency with a certain value as parameter?
All answers I found where like:
#Inject
var myViewModelFactory: MyViewModelAssistedFactory;
and
val initValue = 4
fun onCreate(){
val viewModel = myViewModelFactory.create(initValue)
}
but that doesn't work inside a composable fun.
Not sure if still relevant but if you use the navigation component you can just call hiltViewModel() in the navgraph builder.
Example:
https://github.com/pablichjenkov/ComposeStudy/blob/04298ca8393d3eea0f5b7883fb223161ef79a962/app/src/main/java/com/pablichj/study/compose/home/HomeNavigation.kt#L24
If not using Jetpack Navigation then the solution is a bit more complex. You will need to create a State tree in your App where they implement LifecycleOwner and ViewModelStoreOwner, in order to be able to install the ViewModel appropriately. The good news is that there is work out there already doing so, check this:
https://github.com/Syer10/voyager

Kotlin how to make a ViewBinding by viewBindings() similar to ViewModel by viewModels()

In Kotlin there is this nice extension function that allows us to write
var viewModel: MyViewModel by viewModels()
Is it possible to have the same thing for ViewBindings?
Currently I am using this (in Activities):
var viewBinding: MyViewBinding by lazy { MyViewBinding.inflate(layoutInflater) }
It works but feels a bit clumsy. I'd rather have it like the following but do not know how to implement that:
var viewBinding: MyViewBinding by viewBindings()
For sure you can write a property delegate for a viewbinding for any class that holds views. You can check out this library for inspiration, or even use it in your project

Using ViewModel default constructor Versus via ViewModelProvider class?

I have an Android ViewModel
class MyVM: ViewModel()
In my activity, I can create an instance of MyVM using either:
val viewModel = MyVM()
or using:
val viewModel = ViewModelProvider(this).get(MyVM::class.java)
They both work as expected. My question is what are the main differences between the two

I'm trying to implement MVVM Architecture, but this error is consuming me... (ViewModelProvider)

just it's me trying to implement MVVM architecture with Kotlin. I need to use ViewModelProvider to init my instance and I'm getting this error...
Any advice?
You have a no of options to to instantiate viewmodels.
Now You can now use the ViewModelProvider constructor directly.
private val assignmentViewModel= ViewModelProvider(this).get(AssignmentViewModel::class.java)
If you use androidx.activity:activity-ktx:$Version in the library you can do this directly
private val assignmentViewModel: AssignmentViewModel by viewModels()
If you're using a viewModelFactory
private val assignmentViewModel= ViewModelProvider(this, viewModelFactory).get(AssignmentViewModel ::class.java)
and private val assignmentViewModel: AssignmentViewModel by viewModels { viewModelFactory } respectively
If you're using Kotlin the easiest way to incorporate a ViewModel in your code is via a property delegate:
Activity/Fragment:
val assignmentViewModel: AssignmentViewModel by viewModels()
Fragment:
val assignmentViewModel: AssignmentViewModel by activityViewModels()
The latter allows you to share data between fragments, since activityViewModels scopes it to the Activity.
See ViewModel Overview for more information.

Android: Add a ViewmodelFactory to a viewModel by NavGaphViewmodels

I'm learning Kotlin and I have a viewModel which is created as navGraphViewModels().
private val viewModel: CreationSignalementViewModel by navGraphViewModels(R.id.creation_signalement_nav_graph)
I would like to know if it's possible to add a ViewModelFactory to this viewModel declaration ?
thank you :)

Categories

Resources