How can I use shared view model in jetpack compose for one textfield?

Viewed 122

I have one textfield for user phone number, and I want to use this phone number for both register users to Firestore and using it for mobile authentication, so I have two ViewModel and I want to use ShareViewModel for this number textfield, is it possible to use it in android jetpack compose?

AuthViewModel:

    @HiltViewModel
    class AuthenticationViewModel @Inject constructor(
    
        val auth: FirebaseAuth
    
        ) : ViewModel() {
    
  .....
    
    
    
        }

RegisterViewModel :

   @HiltViewModel
    class RegisterViewModel @Inject constructor(
        val db: FirebaseFirestore,
        val auth: FirebaseAuth,
   
    
    ) : ViewModel() {
    
 
      ......
        }


    

RegisterScreen :

    @OptIn(ExperimentalComposeUiApi::class)
    @Composable
    fun RegisterScreen(
    
        navController: NavController,
        model: RegisterViewModel
    
    ) {
    
       val phoneNumberState = remember { mutableStateOf("") }
    
        OutlinedTextField(
                value = phoneNumberState.value,
                colors = TextFieldDefaults.textFieldColors(
                    backgroundColor = white,
                    focusedIndicatorColor = Grey,
                    unfocusedIndicatorColor = Grey,
                    focusedLabelColor = Grey,
                    unfocusedLabelColor = Grey,
                    cursorColor = custom,
                    textColor = custom,
    
                    ),
                onValueChange = { phoneNumberState.value = it },
                label = { Text(text = "Phone Number") },
                keyboardActions = KeyboardActions(onNext = {
                    focusManager.moveFocus(FocusDirection.Down)
                }),
                placeholder = { Text(text = "Phone Number") },
                singleLine = true,
                
                modifier = Modifier.fillMaxWidth(0.8f)
    
            )
    
             Button(
                    modifier = Modifier
                        .width(205.dp)
                        .height(35.dp),
                    onClick = {
                        focus.clearFocus(force = true)
                        model.onSignUp(
                            phoneNumberState.value,
                     
                        )
                        navController.navigate("otp")
    
                    },
                    colors = ButtonDefaults.buttonColors(
                        backgroundColor = custom
                    ),
                    shape = RoundedCornerShape(30)
                ) {
                    Text(
                        text = "Next",
                        style = TextStyle(
                            fontSize = 11.sp,
                            color = white,
    
                 ))
              }}

PhoneVerifyScreen:

@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun PhoneVerifyScreen(
    navController: NavController,
    modelAuthentication: AuthenticationViewModel,
    onClick: (mobileNum: String, otp: String) -> Unit
) {

    val focusManager = LocalFocusManager.current
    val phoneNumberOTP = remember { mutableStateOf("") }

    val context = LocalContext.current
    LaunchedEffect(Unit) {
        println("found activity? ${context.findActivity()}")
        val activity = context.findActivity() ?: return@LaunchedEffect
        modelAuthentication.setActivity(activity)
    }


    Column(
        Modifier.fillMaxSize()
            .clickable(
                indication = null,
                interactionSource = remember { MutableInteractionSource() } 
            ) {keyboardController?.hide()}
        ,
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {


        OutlinedTextField(
            value = phoneNumberOTP.value,
            colors = TextFieldDefaults.textFieldColors(
                backgroundColor = white,
                focusedIndicatorColor = Grey,
                unfocusedIndicatorColor = Grey,
                focusedLabelColor = Grey,
                unfocusedLabelColor = Grey,
                cursorColor = custom,
                textColor = custom,

                ),
            onValueChange = { phoneNumberOTP.value = it },
            label = { Text(text = "Verify code") },
            placeholder = { Text(text = "Verify code") },
            singleLine = true,
            modifier = Modifier.fillMaxWidth(0.8f),

        )


        CompositionLocalProvider(LocalRippleTheme provides NoRippleTheme) {
            Button(
                modifier = Modifier
                    .width(285.dp)
                    .height(55.dp),
                onClick = {

                    modelAuthentication.otpVerification(phoneNumberOTP.value)

                    navController.navigate("profileScreen")


                },
                colors = ButtonDefaults.buttonColors(
                    backgroundColor = custom2
                ),
                shape = RoundedCornerShape(60),
           
            ) {
                Text(
                    text = "Next",
                    style = TextStyle(
                        fontSize = 18.sp,
                        color = white,


             ))
            }}}}
1 Answers

create a viewModel in your MainActivity, and this viewModel will be the shared viewModel, you can pass it to other screens or just pass function that set phone number to that sharedViewModel

class MainActivity : ComponentActivity() {
    private val sharedViewModel by viewModels<SharedViewModel>
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            App(sharedViewModel = sharedViewModel)
        }
    }
}
Related