Skip to content

Instantly share code, notes, and snippets.

@pbprateek
Last active August 16, 2024 13:24

Revisions

  1. pbprateek revised this gist Oct 23, 2023. 1 changed file with 6 additions and 5 deletions.
    11 changes: 6 additions & 5 deletions ComposeScopedViewModelProvider.kt
    Original file line number Diff line number Diff line change
    @@ -66,13 +66,14 @@ class CompositionScopedViewModelStoreOwner(

    override val defaultViewModelCreationExtras: CreationExtras =
    MutableCreationExtras(originalFactoryProvider.defaultViewModelCreationExtras).apply {
    val bundle = Bundle()
    get(DEFAULT_ARGS_KEY)?.let {
    bundle.putAll(it)
    }
    extraParams?.let {
    val savedStateHandlerNew: Bundle? = get(DEFAULT_ARGS_KEY)
    savedStateHandlerNew?.putAll(it)
    if (savedStateHandlerNew != null)
    set(DEFAULT_ARGS_KEY, savedStateHandlerNew)
    bundle.putAll(it)
    }

    set(DEFAULT_ARGS_KEY, bundle)
    }

    override val defaultViewModelProviderFactory: ViewModelProvider.Factory
  2. pbprateek created this gist Aug 17, 2023.
    82 changes: 82 additions & 0 deletions ComposeScopedViewModelProvider.kt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,82 @@
    import android.os.Bundle
    import androidx.compose.runtime.Composable
    import androidx.compose.runtime.RememberObserver
    import androidx.compose.runtime.remember
    import androidx.lifecycle.*
    import androidx.lifecycle.viewmodel.CreationExtras
    import androidx.lifecycle.viewmodel.MutableCreationExtras
    import androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner
    import androidx.lifecycle.viewmodel.compose.viewModel


    //This is creating using help from,Thanks for that
    //https://gist.github.com/manuelvicnt/a2e4c4812243ac1b218b24d0ac8d22bb#file-provideviewmodels-kt

    //This works with hilt

    // This is a way to scope ViewModels to the Composition.
    // However, this doesn't survive configuration changes or procress death on its own.
    // You can handle all config changes in compose by making the activity handle those in the Manifest file
    // e.g. android:configChanges="colorMode|density|fontScale|keyboard|keyboardHidden|layoutDirection|locale|mcc|mnc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|touchscreen|uiMode">


    @Composable
    public inline fun <reified VM : ViewModel> ComposeScopedViewModelProvider(
    key: String? = null,
    extraParams: Bundle? = null
    ): VM {
    val originalViewModelStoreOwner = checkNotNull(LocalViewModelStoreOwner.current) {
    "No ViewModelStoreOwner was provided via LocalViewModelStoreOwner"
    }
    val composeViewModelStoreOwner =
    remember() {
    CompositionScopedViewModelStoreOwner(
    originalViewModelStoreOwner as HasDefaultViewModelProviderFactory,
    extraParams
    )
    }
    return viewModel(viewModelStoreOwner = composeViewModelStoreOwner, key = key)
    }


    class CompositionScopedViewModelStoreOwner(
    private val originalFactoryProvider: HasDefaultViewModelProviderFactory,
    private val extraParams: Bundle?
    ) :
    ViewModelStoreOwner, RememberObserver, HasDefaultViewModelProviderFactory {


    private val viewModelStoreNew = ViewModelStore()


    override val viewModelStore: ViewModelStore = viewModelStoreNew

    override fun onAbandoned() {
    viewModelStore.clear()
    }

    override fun onForgotten() {
    viewModelStore.clear()
    }

    override fun onRemembered() {
    // Nothing to do here
    }


    override val defaultViewModelCreationExtras: CreationExtras =
    MutableCreationExtras(originalFactoryProvider.defaultViewModelCreationExtras).apply {
    extraParams?.let {
    val savedStateHandlerNew: Bundle? = get(DEFAULT_ARGS_KEY)
    savedStateHandlerNew?.putAll(it)
    if (savedStateHandlerNew != null)
    set(DEFAULT_ARGS_KEY, savedStateHandlerNew)
    }

    }

    override val defaultViewModelProviderFactory: ViewModelProvider.Factory
    get() = originalFactoryProvider.defaultViewModelProviderFactory


    }
    15 changes: 15 additions & 0 deletions Example.kt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,15 @@
    @Composable
    fun ExampleCompose(
    modifier: Modifier = Modifier
    ) {
    val mcqViewModel: TestViewModel = ComposeScopedViewModelProvider()

    //or

    val viewModel: TestViewModel = ComposeScopedViewModelProvider(
    key = id,
    extraParams = Bundle().apply {
    putString(EXTRAS_ID, id)
    }
    )
    }