Skip to content

Commit 800e3d5

Browse files
committed
Assisted inject approach
Change-Id: I5fba15921520bc83b13601fa82ae71457d875805
1 parent ed8745c commit 800e3d5

File tree

2 files changed

+37
-44
lines changed

2 files changed

+37
-44
lines changed

app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/interests2pane/InterestsListDetailScreen.kt

Lines changed: 24 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package com.google.samples.apps.nowinandroid.ui.interests2pane
1818

1919
import androidx.activity.compose.BackHandler
2020
import androidx.annotation.Keep
21+
import androidx.compose.animation.AnimatedContent
2122
import androidx.compose.foundation.interaction.MutableInteractionSource
2223
import androidx.compose.foundation.layout.Box
2324
import androidx.compose.material3.LocalMinimumInteractiveComponentSize
@@ -50,13 +51,17 @@ import androidx.compose.ui.layout.layout
5051
import androidx.compose.ui.unit.dp
5152
import androidx.hilt.navigation.compose.hiltViewModel
5253
import androidx.lifecycle.compose.collectAsStateWithLifecycle
54+
import androidx.lifecycle.viewmodel.viewModelFactory
5355
import androidx.navigation.NavGraphBuilder
5456
import androidx.navigation.compose.NavHost
5557
import androidx.navigation.compose.composable
5658
import androidx.navigation.compose.rememberNavController
5759
import com.google.samples.apps.nowinandroid.feature.interests.InterestsRoute
5860
import com.google.samples.apps.nowinandroid.feature.interests.navigation.InterestsRoute
5961
import com.google.samples.apps.nowinandroid.feature.topic.TopicDetailPlaceholder
62+
import com.google.samples.apps.nowinandroid.feature.topic.TopicScreen
63+
import com.google.samples.apps.nowinandroid.feature.topic.TopicViewModel
64+
import com.google.samples.apps.nowinandroid.feature.topic.TopicViewModel_Factory
6065
import com.google.samples.apps.nowinandroid.feature.topic.navigation.TopicRoute
6166
import com.google.samples.apps.nowinandroid.feature.topic.navigation.navigateToTopic
6267
import com.google.samples.apps.nowinandroid.feature.topic.navigation.topicScreen
@@ -126,28 +131,10 @@ internal fun InterestsListDetailScreen(
126131
val route = selectedTopicId?.let { TopicRoute(id = it) } ?: TopicPlaceholderRoute
127132
mutableStateOf(route)
128133
}
129-
var nestedNavKey by rememberSaveable(
130-
stateSaver = Saver({ it.toString() }, UUID::fromString),
131-
) {
132-
mutableStateOf(UUID.randomUUID())
133-
}
134-
val nestedNavController = key(nestedNavKey) {
135-
rememberNavController()
136-
}
137134

138135
fun onTopicClickShowDetailPane(topicId: String) {
139136
onTopicClick(topicId)
140-
if (listDetailNavigator.isDetailPaneVisible()) {
141-
// If the detail pane was visible, then use the nestedNavController navigate call
142-
// directly
143-
nestedNavController.navigateToTopic(topicId) {
144-
popUpTo<DetailPaneNavHostRoute>()
145-
}
146-
} else {
147-
// Otherwise, recreate the NavHost entirely, and start at the new destination
148-
nestedNavHostStartRoute = TopicRoute(id = topicId)
149-
nestedNavKey = UUID.randomUUID()
150-
}
137+
nestedNavHostStartRoute = TopicRoute(id = topicId)
151138
coroutineScope.launch {
152139
listDetailNavigator.navigateTo(ListDetailPaneScaffoldRole.Detail)
153140
}
@@ -207,22 +194,25 @@ internal fun InterestsListDetailScreen(
207194
}
208195
},
209196
) {
210-
key(nestedNavKey) {
211-
NavHost(
212-
navController = nestedNavController,
213-
startDestination = nestedNavHostStartRoute,
214-
route = DetailPaneNavHostRoute::class,
215-
) {
216-
topicScreen(
217-
showBackButton = !listDetailNavigator.isListPaneVisible(),
218-
onBackClick = {
219-
coroutineScope.launch {
220-
listDetailNavigator.navigateBack()
197+
AnimatedContent(nestedNavHostStartRoute) { route ->
198+
when (route) {
199+
is TopicRoute -> {
200+
TopicScreen(
201+
showBackButton = !listDetailNavigator.isListPaneVisible(),
202+
onBackClick = {
203+
coroutineScope.launch {
204+
listDetailNavigator.navigateBack()
205+
}
206+
},
207+
onTopicClick = ::onTopicClickShowDetailPane,
208+
viewModel = hiltViewModel<TopicViewModel, TopicViewModel.Factory>(
209+
key = route.id,
210+
) { factory ->
211+
factory.create(route.id)
221212
}
222-
},
223-
onTopicClick = ::onTopicClickShowDetailPane,
224-
)
225-
composable<TopicPlaceholderRoute> {
213+
)
214+
}
215+
is TopicPlaceholderRoute -> {
226216
TopicDetailPlaceholder()
227217
}
228218
}

feature/topic/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModel.kt

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,8 @@
1616

1717
package com.google.samples.apps.nowinandroid.feature.topic
1818

19-
import androidx.lifecycle.SavedStateHandle
2019
import androidx.lifecycle.ViewModel
2120
import androidx.lifecycle.viewModelScope
22-
import androidx.navigation.toRoute
2321
import com.google.samples.apps.nowinandroid.core.data.repository.NewsResourceQuery
2422
import com.google.samples.apps.nowinandroid.core.data.repository.TopicsRepository
2523
import com.google.samples.apps.nowinandroid.core.data.repository.UserDataRepository
@@ -29,7 +27,9 @@ import com.google.samples.apps.nowinandroid.core.model.data.Topic
2927
import com.google.samples.apps.nowinandroid.core.model.data.UserNewsResource
3028
import com.google.samples.apps.nowinandroid.core.result.Result
3129
import com.google.samples.apps.nowinandroid.core.result.asResult
32-
import com.google.samples.apps.nowinandroid.feature.topic.navigation.TopicRoute
30+
import dagger.assisted.Assisted
31+
import dagger.assisted.AssistedFactory
32+
import dagger.assisted.AssistedInject
3333
import dagger.hilt.android.lifecycle.HiltViewModel
3434
import kotlinx.coroutines.flow.Flow
3535
import kotlinx.coroutines.flow.SharingStarted
@@ -38,18 +38,14 @@ import kotlinx.coroutines.flow.combine
3838
import kotlinx.coroutines.flow.map
3939
import kotlinx.coroutines.flow.stateIn
4040
import kotlinx.coroutines.launch
41-
import javax.inject.Inject
4241

43-
@HiltViewModel
44-
class TopicViewModel @Inject constructor(
45-
savedStateHandle: SavedStateHandle,
42+
@HiltViewModel(assistedFactory = TopicViewModel.Factory::class)
43+
class TopicViewModel @AssistedInject constructor(
4644
private val userDataRepository: UserDataRepository,
4745
topicsRepository: TopicsRepository,
4846
userNewsResourceRepository: UserNewsResourceRepository,
47+
@Assisted val topicId: String,
4948
) : ViewModel() {
50-
51-
val topicId = savedStateHandle.toRoute<TopicRoute>().id
52-
5349
val topicUiState: StateFlow<TopicUiState> = topicUiState(
5450
topicId = topicId,
5551
userDataRepository = userDataRepository,
@@ -89,6 +85,13 @@ class TopicViewModel @Inject constructor(
8985
userDataRepository.setNewsResourceViewed(newsResourceId, viewed)
9086
}
9187
}
88+
89+
@AssistedFactory
90+
interface Factory {
91+
fun create(
92+
topicId: String,
93+
): TopicViewModel
94+
}
9295
}
9396

9497
private fun topicUiState(

0 commit comments

Comments
 (0)