Giter Site home page Giter Site logo

Comments (6)

emredagci avatar emredagci commented on May 21, 2024 12

If you would like to use two frameworks together, you should define a new extension then you can use the koin framework with scene framework.


import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.*
import com.bytedance.scene.Scene
import org.koin.android.viewmodel.*
import org.koin.core.Koin
import org.koin.core.context.GlobalContext
import org.koin.core.parameter.ParametersDefinition
import org.koin.core.qualifier.Qualifier
import org.koin.core.scope.Scope
import kotlin.reflect.KClass

inline fun <reified T : ViewModel> LifecycleOwner.customViewModel(
    qualifier: Qualifier? = null,
    noinline parameters: ParametersDefinition? = null
): Lazy<T> = lazy { getViewModelCustom(qualifier, parameters) }

inline fun <reified T : ViewModel> LifecycleOwner.getViewModelCustom(
    qualifier: Qualifier? = null,
    noinline parameters: ParametersDefinition? = null
): T {
    return getViewModelCustom(T::class, qualifier, parameters)
}

fun <T : ViewModel> LifecycleOwner.getViewModelCustom(
    clazz: KClass<T>,
    qualifier: Qualifier? = null,
    parameters: ParametersDefinition? = null
): T {
    return GlobalContext.get().koin.getViewModelCustom(
        ViewModelParameters(
            clazz,
            this@getViewModelCustom,
            qualifier,
            parameters = parameters
        )
    )
}

fun <T : ViewModel> Koin.getViewModelCustom(parameters: ViewModelParameters<T>): T {
    val vmStore: ViewModelStore = parameters.owner.getViewModelStoreCustom(parameters)
    val viewModelProvider = rootScope.createViewModelProviderCustom(vmStore, parameters)
    return viewModelProvider.getInstanceCustom(parameters)
}

fun <T : ViewModel> ViewModelProvider.getInstanceCustom(parameters: ViewModelParameters<T>): T {
    val javaClass = parameters.clazz.java
    return if (parameters.qualifier != null) {
        this.get(parameters.qualifier.toString(), javaClass)
    } else {
        this.get(javaClass)
    }
}

fun <T : ViewModel> LifecycleOwner.getViewModelStoreCustom(
    parameters: ViewModelParameters<T>
): ViewModelStore =
    when {
        parameters.from != null -> parameters.from!!.invoke().viewModelStore
        this is FragmentActivity -> ViewModelStores.of(this)
        this is Fragment -> ViewModelStores.of(this)
        this is Scene -> this.viewModelStore
        else -> error("Can't getByClass ViewModel '${parameters.clazz}' on $this - Is not a FragmentActivity nor a Fragment neither a valid ViewModelStoreOwner")
    }

fun <T : ViewModel> Scope.createViewModelProviderCustom(
    vmStore: ViewModelStore,
    parameters: ViewModelParameters<T>
): ViewModelProvider {
    return ViewModelProvider(
        vmStore,
        object : ViewModelProvider.Factory {
            override fun <T : ViewModel> create(modelClass: Class<T>): T {
                return get(parameters.clazz, parameters.qualifier, parameters.parameters)
            }
        })
}

After you created the extension you can use like code shown below.

class SplashScene : Scene() {

    private val splashViewModel: SplashViewModel by customViewModel()

}

from scene.

qii avatar qii commented on May 21, 2024 1

你可以搞个子类实现这个接口,然后 onActivityCreateed 里面通过 NavigationScene.addConfigurationXXXX 的转发给自己的方法,其实我感觉 koin 的这个要求很奇怪

from scene.

Ccixyj avatar Ccixyj commented on May 21, 2024 1

另外一种是自己写一个LifecycleOwner.getKoin()的扩展方法。然后通过getkoin().getViewModel(lifecycleowner....)手动实现一个viewmodl代理方法。

fun LifecycleOwner.getKoin(): Koin = when (this) {
    is KoinComponent -> this.getKoin()
    is Scene -> ((this as? KoinComponent)?.getKoin()
        ?: (this.requireActivity() as? KoinComponent)?.getKoin()
        ?: error("scene attach parent must be KoinComponent"))
    else -> KoinContextHandler.get()
}

from scene.

qii avatar qii commented on May 21, 2024

蛋疼啊,Scene 不想有 onConfigurationChanged 这些

from scene.

chachako avatar chachako commented on May 21, 2024

蛋疼啊,Scene 不想有 onConfigurationChanged 这些

好的,那我手动改改吧...

from scene.

ZhaoSiBo avatar ZhaoSiBo commented on May 21, 2024

i use koin version is 3.2.0,scene version is 1.3.1
i used code

import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelStoreOwner
import com.bytedance.scene.Scene
import com.bytedance.scene.ktx.viewModels
import org.koin.android.scope.getScopeOrNull
import org.koin.androidx.viewmodel.ext.android.getViewModelFactory
import org.koin.core.annotation.KoinInternalApi
import org.koin.core.component.getScopeId
import org.koin.core.component.getScopeName
import org.koin.core.context.GlobalContext
import org.koin.core.parameter.ParametersDefinition
import org.koin.core.qualifier.Qualifier


@OptIn(KoinInternalApi::class)
inline fun <reified T : ViewModel> Scene.viewModel(
    qualifier: Qualifier? = null,
    owner : ViewModelStoreOwner = this,
    noinline parameters: ParametersDefinition? = null
): Lazy<T> {
    val scope = GlobalContext.get().createScope(getScopeId(), getScopeName())
    val activityScope = activity?.getScopeOrNull()
    activityScope?.let { scope.linkTo(it) }
    return viewModels{
        getViewModelFactory<T>(owner, qualifier, parameters, scope = scope)
    }
}

after i used like code below

class DiscoverScene : AppCompatScene() {
    
    private val model: DiscoverViewModel by viewModel()
    
}

from scene.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.