Here is my MainActivity.kt file
Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) {
NavigationHoster()
}
here is navhoster function
@Composable
fun NavigationHoster(){
val navController = rememberNavController();
NavHost(navController = navController, startDestination = "Home"){
composable("Home"){ HomeScreen(navController = navController)}
composable("Chat"){ ChatScreen()}
}
}
here is HomeScreen Function
@OptIn(ExperimentalMaterial3Api::class)
//@Preview(showBackground = true, showSystemUi = true)
@Composable
fun HomeScreen(
homeViewModel: HomeViewModel = viewModel(),
navController: NavController
){
val HomeViewState by homeViewModel.uiState.collectAsState()
Scaffold (
topBar = {
TopAppBar(title = {
Text(text = "Chat Wallet", style = MaterialTheme.typography.titleMedium)
}, colors = TopAppBarDefaults.mediumTopAppBarColors(
containerColor = MaterialTheme.colorScheme.primary,
titleContentColor = MaterialTheme.colorScheme.background
))
}
){
paddingValues -> Box(modifier = Modifier.padding(paddingValues).fillMaxSize(), contentAlignment = Alignment.Center) {
IconButton(onClick = { navController.navigate("Chat") }, colors = IconButtonDefaults.iconButtonColors(containerColor = MaterialTheme.colorScheme.primary)) {
Icon(painter = painterResource(id = R.drawable.baseline_chat_24), contentDescription = null, tint = MaterialTheme.colorScheme.background)
}
}
}
}
Here is my ViewModel
class HomeViewModel : ViewModel(){
private var _uiState = MutableStateFlow(HomeData())
var uiState : StateFlow<HomeData> = _uiState.asStateFlow()
public fun ChangeName() {
_uiState.value = HomeData(UserName = "hello there")
}
}
These codes are works well and I tested. this viewmodel and screen file may be not linked.because I does different tests by changing it. can I know how to navigate to chat screen by calling changeName function from ui? I have no idea how to implement it
I didn't get any way to import navcontroller to viewmodel. so I stucked with that point. I thaught it have to import to viewmodel.
please give me simple example as well. thank you.
You best approach would be to add a variable to the viewModel called navigateToChatScreen and then when this variable is true you can navigate in your composable like this:
class HomeViewModel : ViewModel(){
private var _uiState = MutableStateFlow(HomeData())
var uiState : StateFlow<HomeData> = _uiState.asStateFlow()
private var _navigateToChatScreen = MutableStateFlow(false)
var navigateToChatScreen : StateFlow<Boolean> = _navigateToChatScreen.asStateFlow()
public fun ChangeName() {
_uiState.value = HomeData(UserName = "hello there")
_navigateToChatScreen.value = true
}
}
Then you do it like this in your composable:
@Composable
fun HomeScreen(
homeViewModel: HomeViewModel = viewModel(),
navController: NavController
){
val HomeViewState by homeViewModel.uiState.collectAsState()
val navigateToChatScreen by homeViewModel.navigateToChatScreen.collectAsState()
Launchedeffect(key= navigateToChatScreen){
If(navigateToChatScreen){
navController.navigate("chat")
}
}
Scaffold (
topBar = {
TopAppBar(title = {
Text(text = "Chat Wallet", style = MaterialTheme.typography.titleMedium)
}, colors = TopAppBarDefaults.mediumTopAppBarColors(
containerColor = MaterialTheme.colorScheme.primary,
titleContentColor = MaterialTheme.colorScheme.background
))
}
){
paddingValues -> Box(modifier = Modifier.padding(paddingValues).fillMaxSize(), contentAlignment = Alignment.Center) {
IconButton(onClick = { homeViewModel.changeName()}, colors = IconButtonDefaults.iconButtonColors(containerColor = MaterialTheme.colorScheme.primary)) {
Icon(painter = painterResource(id = R.drawable.baseline_chat_24), contentDescription = null, tint = MaterialTheme.colorScheme.background)
}
}
}
}