Я хочу использовать тот же экземпляр модели представления в koin в навигации по созданию реактивного ранца. Я знаю, что в koinViewModel() есть функция для получения экземпляра viewModel. Недавно я видел, что в документации Koin есть отдельный файл koin-androidx-compose-navigation, который предоставляет функцию koinNavViewModel().
build.gradle.kts
dependencies {
implementation("androidx.core:core-ktx:1.12.0")
implementation("io.insert-koin:koin-android:3.4.0")
implementation("io.insert-koin:koin-androidx-workmanager:3.4.0")
implementation("io.insert-koin:koin-androidx-compose:3.4.6")
implementation("io.insert-koin:koin-androidx-compose-navigation:3.4.6")
implementation(platform("androidx.compose:compose-bom:2023.06.01"))
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.foundation:foundation")
implementation("androidx.compose.foundation:foundation-layout")
implementation("androidx.compose.material:material")
implementation("androidx.compose.material3:material3")
implementation("androidx.compose.runtime:runtime")
implementation("androidx.compose.runtime:runtime-livedata")
implementation("androidx.compose.ui:ui-tooling")
implementation("androidx.compose.ui:ui-tooling-preview")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose")
implementation("androidx.activity:activity-compose:1.7.0")
implementation("androidx.lifecycle:lifecycle-runtime-compose:$2.6.2")
implementation("androidx.navigation:navigation-compose:$2.6.0")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
androidTestImplementation(platform("androidx.compose:compose-bom:2023.08.00"))
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
debugImplementation("androidx.compose.ui:ui-tooling")
debugImplementation("androidx.compose.ui:ui-test-manifest")
}
Теперь я пытаюсь использовать одну модель представления на разных экранах. Когда я получаю некоторые данные в модели представления, я сохраняю их в SharedFlow и перехожу на другой экран с тем же экземпляром модели представления, который дает мне нулевую переменную.
MainActivity .kt
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
SimpleComposeNavigationTheme {
SimpleNavigation()
}
}
}
}
Простая навигация
@Composable
fun SimpleNavigation(navController: NavHostController = rememberNavController()) {
NavHost(
navController = navController,
startDestination = navController.currentBackStackEntry?.destination?.route ?: "first_screen"
) {
composable("first_screen") {
val viewModel: FirstViewModel = koinNavViewModel()
Surface {
Column(Modifier.fillMaxSize()) {
Button(onClick = { viewModel.updateName("Hello world") }) {
Text(text = "Add Name")
}
Button(onClick = { navController.navigate("second_screen") }) {
Text(text = "Next Screen")
}
}
}
}
composable("second_screen") {
val viewModel: FirstViewModel = koinNavViewModel()
val firstName by viewModel.firstName.collectAsState()
LaunchedEffect(firstName){
println(">> $firstName")
}
Surface {
Column(Modifier.fillMaxSize()) {
firstName?.let { name -> Text(text = name) }
}
}
}
}
}
FirstViewModel.kt
class FirstViewModel : ViewModel() {
private val _firstName = MutableSharedFlow()
val firstName: SharedFlow = _firstName.asSharedFlow()
fun updateName(name: String) {
viewModelScope.launch {
_firstName.emit(name)
}
}
}
SampleApplication.kt
class SampleApplication : Application() {
override fun onCreate() {
super.onCreate()
initializeDependencyInjection()
}
private fun initializeDependencyInjection() {
startKoin {
androidLogger(Level.ERROR)
modules(
listOf(simpleModule)
)
}
}
}
val simpleModule = module {
viewModelOf(::FirstViewModel)
}
Каковы преимущества использования koinNavViewModel(), если мы не можем использовать один и тот же экземпляр на разных экранах создания посредством навигации.
Я знаю, что есть еще один вопрос по использованию другого класса для хранения всех этих данных и получения данных. Хочу лучше подходить через коин. Спасибо
ОБНОВЛЕНИЕ
Я не хочу создавать модель представления на глобальном уровне и передавать экземпляр в каждый из них. функция.
ОБНОВЛЕНИЕ 1
Я попробовал предложение Hiren-rafaliya и benjytec, и оно работает
@Composable
fun SimpleNavigation(navController: NavHostController = rememberNavController()) {
NavHost(navController = navController, startDestination = "screenA", route = "parentRoute") {
composable("screenA") {
// create backstack entry from parent route which was passed in NavHost
val backStackEntry = remember(it) { navController.getBackStackEntry("parentRoute") }
// pass the backstack entry as viewModelStoreOwner
val viewModel: MainViewModel = koinNavViewModel(viewModelStoreOwner = backStackEntry)
ScreenA(viewModel) {
navController.navigate("screenB")
}
}
composable("screenB") {
// create backstack entry from parent route which was passed in NavHost
val backStackEntry = remember(it) { navController.getBackStackEntry("parentRoute") }
// pass the backstack entry as viewModelStoreOwner
val viewModel: MainViewModel = koinNavViewModel(viewModelStoreOwner = backStackEntry)
ScreenB(viewModel) {
navController.navigate("screenA")
}
}
}
}
@Composable
fun ScreenA(viewModel: MainViewModel, onNavigate: () -> Unit) {
val firstName by viewModel.firstName
Column {
Text(text = "SCREEN A")
Text(text = "MainViewModel.firstname = $firstName")
Button(onClick = {
viewModel.updateName("ABC")
}) {
Text(text = "MainViewModel.firstname = ABC")
}
Button(onClick = onNavigate) {
Text(text = "Go to SCREEN B")
}
}
}
@Composable
fun ScreenB(viewModel: MainViewModel, onNavigate: () -> Unit) {
val firstName by viewModel.firstName
Column {
Text(text = "SCREEN B")
Text(text = "firstname = $firstName")
Button(onClick = {
viewModel.updateName("DEF")
}) {
Text(text = "MainViewModel.firstname = DEF")
}
Button(onClick = onNavigate) {
Text(text = "Go to SCREEN A")
}
}
}
class MainViewModel : ViewModel() {
private val _firstName = mutableStateOf(null)
val firstName: State = _firstName
fun updateName(name: String) {
viewModelScope.launch {
_firstName.value = name
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/779 ... navigation
Как поделиться одним и тем же экземпляром модели представления в навигации по созданию koin ⇐ Android
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Почему «объект» является экземпляром «типа», а «тип» — экземпляром «объекта»?
Anonymous » » в форуме Python - 0 Ответы
- 30 Просмотры
-
Последнее сообщение Anonymous
-