android 如何在Kotlincompose中的viewmodel中使用viewmodel?

4smxwvx5  于 2023-04-04  发布在  Android
关注(0)|答案(1)|浏览(195)

我写了一段代码,在用户登录后保存令牌,如果令牌产生,则跳过开始屏幕,直接进入主屏幕。我认为我应该在viewmodel的init函数中执行此操作,以直接进入主屏幕,因为如果我在ui中执行此操作,通常首先加载ui并出现屏幕,然后进入主屏幕,但我希望它直接进入init函数,所以我想在viewmodel的init函数中完成。我以为这会是真的。然而,当我将令牌管理器视图模型注入开始屏幕viewmodel时,出现以下错误。
实际上我不认为这是最好的解决方案,那么在视图模型中使用另一个视图模型有多正确呢?如果这不是一个最佳实践方法,我怎么能把它作为最佳解决方案呢?
[dagger.hilt.android.processor.internal.viewmodel.ViewModelValidationPlugin]禁止注入@HiltViewModel类,因为它不能正确创建ViewModel示例。请改为通过Android API(例如ViewModelProvider)访问ViewModel。注入的ViewModel:

hear是我的开始屏幕视图模型

@HiltViewModel
class StartScreenViewModel @Inject constructor(
    private val tokenViewModel: TokenViewModel
) : ViewModel() {

    private val _viewState = MutableStateFlow(StartScreenViewState.initial)
    var viewState = _viewState.asStateFlow()

    var tokenState by mutableStateOf<String?>(null)
        private set

    init {
        getToken()
    }

  
    private fun getToken() {

        if(tokenViewModel.token.value != null){
            _viewState.update {
                it.copy(
                    shouldNavigate = true
                )
            }
        }
    }
}

data class StartScreenViewState(
    var shouldNavigate:Boolean
) {
    companion object {
        val initial = StartScreenViewState(
            shouldNavigate = false
        )
    }
}

开始画面

LaunchedEffect(key1 = state, block = {
        if(state.shouldNavigate){
            navController.navigate(BOTTOM_BAR_ROUTE)
        }
    })

token视图模型

@HiltViewModel
class TokenViewModel @Inject constructor(
    private val tokenManager: TokenManager
) : ViewModel() {

    private val _token = MutableStateFlow<String?>(null)
    val token:StateFlow<String?> = _token.asStateFlow()

    init {
        viewModelScope.launch(Dispatchers.IO) {
            tokenManager.getToken().collect {
                withContext(Dispatchers.Main) {
                    _token.value = it
                }
            }
        }
    }

    fun saveToken(token:String){
        viewModelScope.launch(Dispatchers.IO){
            tokenManager.saveToken(token)
        }
    }

    fun deleteToken(){
        viewModelScope.launch(Dispatchers.IO) {
            tokenManager.deleteToken()
        }
    }
}
5kgi1eie

5kgi1eie1#

你不能把一个视图模型放到另一个视图模型中。请使用你的TokenManager

class StartScreenViewModel @Inject constructor(
    private val tokenManager: TokenManager
) : ViewModel() {

...
    private fun getToken() {
        val theToken = tokenManager.getToken()
        ...
    }
}

相关问题