如何在Composable和Activity中获取相同的ViewModel实例?

问题描述 投票:0回答:1

在我的 android 项目(jetpack compose)中,我有一个活动,在 onTagDiscovered 方法中,我收到一条从 NFC 标签读取的消息,我想将其传递给当前活动的 viewModel,在其中我将执行多个操作(发送到数据库) ,通知用户等)。 我遇到的问题是获取活动中当前活动视图模型的实例(而不是创建一个新视图模型)。 如果我在代码中执行以下操作,我会收到(在日志中显示)两个单独的实例,这些实例不适合进一步操作。 日志:

  • 可组合 ViewModel 实例:com.myapp.screens.registration_device.register_by_nfc.RegisterByNfcViewModel@7fb2d78
  • onTagDiscovered ViewModel 实例:com.myapp.screens.registration_device.register_by_nfc.RegisterByNfcViewModel@b7c078e

在我的屏幕可组合项中,我使用 hilt 来获取视图模型实例:

@Composable
fun RegisterByNfcScreen(navController: NavController, startOrEnd:String) {
    val registerByNfcViewModel:RegisterByNfcViewModel = hiltViewModel()

    Log.d("myLog","composable ViewModel instance:  $registerByNfcViewModel")
}

我的视图模型:

@HiltViewModel
class RegisterByNfcViewModel @Inject constructor(
    private val firebaseAuth: FirebaseAuth,
    private val iFirestoreManager: FirestoreManager,
    private val sharedPrefsManager: SharedPrefsManager
): ViewModel(){
}

活动:

@AndroidEntryPoint
class MainActivity : ComponentActivity(),NfcAdapter.ReaderCallback {
    private lateinit var nfcAdapter: NfcAdapter
    private lateinit var userType:UserType
    
    private val registerByNfcViewModel: RegisterByNfcViewModel by viewModels()


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        userType = SharedPrefsManager(this).getUserData().userType

        setContent {
            MyAppTheme {
                val navController = rememberNavController()
                SetUpNavGraph(navController = navController)
            }
        }
            }
override fun onTagDiscovered(tag: Tag?) {
    Log.d("myLog","onTagDiscovered ViewModel instance:  $registerByNfcViewModel")
//some operation
registerByNfcViewModel.saveDataToDb(userName,company)

}
}

如何像可组合函数中那样使某些视图模型实例处于活动状态?

kotlin mvvm android-jetpack-compose instance viewmodel
1个回答
0
投票

我终于设法自己使用 NavBackStackEntry 解决了这个问题。 Viewmodel 和 Composable 保持不变。我只改变了活动如下。从 backstackentry 获取的 Viewmodel 实例是我的可组合屏幕中的某个实例。

private lateinit var registerByNfcViewModel: RegisterByNfcViewModel

override fun onTagDiscovered(tag: Tag?) {
    val currentBackStackEntry = navController.currentBackStackEntry
            currentBackStackEntry?.let { navBackStackEntry ->
                registerByNfcViewModel =
                     ViewModelProvider(navBackStackEntry)[RegisterByNfcViewModel::class.java]
            }

}

© www.soinside.com 2019 - 2024. All rights reserved.