How I can clear data of viewmodel while navigate back in compose android

Viewed 29

I am using Compose and dagger

I declared viewmodels in activity and passed it to compose screens.

I have two screens A & B.

Problem :- A -> B -> A(by pressing back) -> B(here need fresh value but getting old data from viewmodel)

How can I clear data from view model ?

Code

MainActivity

 CompositionLocalProvider(
                        LocalLayoutDirection
                            provides
                            if (preferenceHelper.userLanguage == "en") LayoutDirection.Ltr else LayoutDirection.Rtl
                    ) {
                        AppNavigation(
                            viewmodelA= ViewModelA,
                            viewModelB= ViewModelB
                        )
                    }

App Nav


@Composable
fun AppNavigation(
    modifier: Modifier = Modifier,
    viewmodelA= ViewmodelA,
    viewmodelB= ViewmodelB
) {
    val navController = rememberNavController()
    val scaffoldState: ScaffoldState = rememberScaffoldState()
    Scaffold(
        scaffoldState = scaffoldState
    ) {
        NavHost(navController = navController, startDestination = A_SCREEN) {
            composable(route = A_SCREEN) {
                ScreenA(
                    navController = navController,
                    scaffoldState = scaffoldState,
                    viewmodelA= ViewmodelA
                )
            }
            composable(route = B_SCREEN) {
                ScreenB(
                    navController = navController,
                    scaffoldState = scaffoldState,
                    viewmodelB= ViewmodelB
                )
            }
        }
    }

}

Screen A

@Composable
fun ScreenA(
    navController: NavController,
    scaffoldState: ScaffoldState,
    viewmodelA: ViewModelA
) {
   
    Column {
        ToolBar(navConroller=navController )
        ButtonView( viewmodelA: ViewModelA) {
            navController.navigate(route = B_SCREEN)
        }
        DividerView()
       ...
    }
}

Screen B

@Composable
fun ScreenB(
    navController: NavController,
    scaffoldState: ScaffoldState,
    viewmodelB: ViewModelB
) {
   
     val amount by remember { viewmodelB.amountValue }
    Column {
        ToolBar(navConroller=navController )
        DividerView()
        BasicTextField(
                    value = amount,
                    onValueChange = {
                        viewmodelB.updateAmount(it)
                    },
                    modifier = Modifier
                        .background(color = Color.White)
                        .width(IntrinsicSize.Min)
                        .align(Alignment.CenterVertically),
            
                    decorationBox = { innerTextField ->
                        Row {
                            if (amount.isEmpty()) {
                                Text(
                                    "0",   
                                )
                            }
                            innerTextField()
                        }
                    },

       ...
    }
}

ViewModel B

class ViewModelB @Inject constructor(private val remoteRepository: RemoteRepository) : ViewModel() {

     val amountValue = mutableStateOf("")

     fun updateAmount(value: String) {
        amountValue.value = value
    }
}

How can I get an empty amount string when I enter screen B again?

Please help :).

1 Answers

You must create viewmodels in screens;

@Composable
fun ScreenA(
    viewmodelA: ViewModelA = hiltViewModel()
) {
   //
}

You can navigate via backhandler so your viewmodel instance recreate via hilt;

BackHandler {
   navController.navigate(
      route = //ROUTE TO B
   )
}

But,

You are create viewmodel instance in activity and passed to screens, indeed there is a way to do this but i think it will be inefficient. So you must think about your architecture for your needs.

Related