Home > Blockchain >  How send the value to child compose which is viewmodel value?
How send the value to child compose which is viewmodel value?

Time:11-23

Here is my code.

DrawerCompose

@Composable
fun DrawerCompose(
    modifier: Modifier = Modifier,
    onDestinationClicked: (route: String) -> Unit
) {
    val versionName = BuildConfig.VERSION_NAME

    val empno by remember {
        mutableStateOf("")
    }
    val password by remember {
        mutableStateOf("")
    }

    Column(
        modifier = Modifier
            .background(MaterialTheme.colors.primarySurface)
            .fillMaxSize()
    ) {
        Box(
            modifier = Modifier
                .fillMaxWidth()
        ) {
            Column(
                modifier = Modifier
                    .padding(20.dp)
            ) {
                Text(
                    text = "Title",
                    fontSize = 25.sp,
                    textAlign = TextAlign.Center,
                    fontWeight = FontWeight.Bold,
                    color = Color.White
                )
                Spacer(modifier = Modifier.height(16.dp))
                Text(
                    text = "ID",
                    fontSize = 25.sp,
                    textAlign = TextAlign.Center,
                    fontWeight = FontWeight.Bold,
                    color = Color.White
                )
                OutlinedTextField(
                    value = empno,
                    onValueChange = {

                    },
                    modifier = Modifier
                        .fillMaxWidth(),
                    label = { Text(text = "ID") },
                    singleLine = true,
                    keyboardOptions = KeyboardOptions(
                        keyboardType = KeyboardType.Number,
                        imeAction = ImeAction.Next
                    ),
                    keyboardActions = KeyboardActions(
                        onNext = {

                        }
                    )
                )
                Text(
                    text = "Password",
                    fontSize = 25.sp,
                    textAlign = TextAlign.Center,
                    fontWeight = FontWeight.Bold,
                    color = Color.White
                )
                OutlinedTextField(
                    value = password,
                    onValueChange = {

                    },
                    modifier = Modifier
                        .fillMaxWidth(),
                    label = { Text(text = "Password") },
                    singleLine = true,
                    keyboardOptions = KeyboardOptions(
                        keyboardType = KeyboardType.Number,
                        imeAction = ImeAction.Done
                    ),
                    keyboardActions = KeyboardActions(
                        onDone = {

                        }
                    )
                )
                Text(
                    text = "v $versionName",
                    fontSize = 25.sp,
                    textAlign = TextAlign.Center,
                    fontWeight = FontWeight.Bold,
                    color = Color.White
                )
            }
        }
    }
}

MenuListScreen

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun HomeScreen(
    navController: NavController,
    onNavigateToMenuDetailScreen: (String) -> Unit,
    viewModel: MenuListViewModel,
) {
    val context = LocalContext.current

    val menuList = viewModel.menuList.value

    val scope = rememberCoroutineScope()
    val scaffoldState = rememberScaffoldState(
        rememberDrawerState(initialValue = DrawerValue.Closed)
    )

    val loading = viewModel.loading.value
    val dialogQueue = viewModel.dialogQueue

    Scaffold(
        modifier = Modifier.fillMaxSize(),
        topBar = {
            TopAppBarCompose(
                title = "Title",
                navigationIcon = {
                    IconButton(onClick = {
                        scope.launch {
                            scaffoldState.drawerState.open()
                        }
                    }) {
                        Icon(imageVector = Icons.Filled.Menu, contentDescription = "")
                    }
                }
            )
        },
        scaffoldState = scaffoldState,
        drawerContent = {
            DrawerCompose(
                onDestinationClicked = { route ->
                    scope.launch {
                        scaffoldState.drawerState.close()
                    }
                }
            )
        },
        drawerGesturesEnabled = true
    ) {
        MenuList(
            loading = loading,
            menus = menuList,
            onNavigateToSubmenuScreen = onNavigateToMenuDetailScreen
        )
    }
}

MenuListViewModel

@HiltViewModel
class MenuListViewModel @Inject constructor(
    private val restoreMenus: RestoreMenus,
    private val assetsManager: AssetsManager,
    private val savedStateHandle: SavedStateHandle
) : ViewModel() {
    val id: MutableState<String> = mutableStateOf("")
    val password: MutableState<String> = mutableStateOf("")

    fun onChangeEmpNo(id: String) {
        this.id.value = id
    }
    fun onChangePassword(password: String) {
        this.password.value = password
    }
}

If the value in the ID TextField in the drawer changes, the empno value in the viewModel changes, and if the value in the ID in the viewModel changes, the value in the ID TextField in the drawer changes.

enter image description here

I'd like to know how to communicate with Viewmodel and Child Compose.

Edit I solved that pass the viewmodel variables to drawer, and viewmodel function

CodePudding user response:

You have to pass callback function

 @Composable
    fun DrawerCompose(
        modifier: Modifier = Modifier,
        onDestinationClicked: (route: String) -> Unit,
        onIdChange: (value: String) -> Unit,
        onPasswordChange: (value: String) -> Unit,
    ) {
        val versionName = BuildConfig.VERSION_NAME
    
        val empno by remember {
            mutableStateOf("")
        }
        val password by remember {
            mutableStateOf("")
        }
    
        Column(
            modifier = Modifier
                .background(MaterialTheme.colors.primarySurface)
                .fillMaxSize()
        ) {
            Box(
                modifier = Modifier
                    .fillMaxWidth()
            ) {
                Column(
                    modifier = Modifier
                        .padding(20.dp)
                ) {
                    Text(
                        text = "Title",
                        fontSize = 25.sp,
                        textAlign = TextAlign.Center,
                        fontWeight = FontWeight.Bold,
                        color = Color.White
                    )
                    Spacer(modifier = Modifier.height(16.dp))
                    Text(
                        text = "ID",
                        fontSize = 25.sp,
                        textAlign = TextAlign.Center,
                        fontWeight = FontWeight.Bold,
                        color = Color.White
                    )
                    OutlinedTextField(
                        value = empno,
                        onValueChange = onIdChange,
                        modifier = Modifier
                            .fillMaxWidth(),
                        label = { Text(text = "ID") },
                        singleLine = true,
                        keyboardOptions = KeyboardOptions(
                            keyboardType = KeyboardType.Number,
                            imeAction = ImeAction.Next
                        ),
                        keyboardActions = KeyboardActions(
                            onNext = {
    
                            }
                        )
                    )
                    Text(
                        text = "Password",
                        fontSize = 25.sp,
                        textAlign = TextAlign.Center,
                        fontWeight = FontWeight.Bold,
                        color = Color.White
                    )
                    OutlinedTextField(
                        value = password,
                        onValueChange = onPasswordChange,
                        modifier = Modifier
                            .fillMaxWidth(),
                        label = { Text(text = "Password") },
                        singleLine = true,
                        keyboardOptions = KeyboardOptions(
                            keyboardType = KeyboardType.Number,
                            imeAction = ImeAction.Done
                        ),
                        keyboardActions = KeyboardActions(
                            onDone = {
    
                            }
                        )
                    )
                    Text(
                        text = "v $versionName",
                        fontSize = 25.sp,
                        textAlign = TextAlign.Center,
                        fontWeight = FontWeight.Bold,
                        color = Color.White
                    )
                }
            }
        }
    }

After that pass those function from main screen

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun HomeScreen(
    navController: NavController,
    onNavigateToMenuDetailScreen: (String) -> Unit,
    viewModel: MenuListViewModel,
) {
    val context = LocalContext.current

    val menuList = viewModel.menuList.value

    val scope = rememberCoroutineScope()
    val scaffoldState = rememberScaffoldState(
        rememberDrawerState(initialValue = DrawerValue.Closed)
    )

    val loading = viewModel.loading.value
    val dialogQueue = viewModel.dialogQueue

    Scaffold(
        modifier = Modifier.fillMaxSize(),
        topBar = {
            TopAppBarCompose(
                title = "Title",
                navigationIcon = {
                    IconButton(onClick = {
                        scope.launch {
                            scaffoldState.drawerState.open()
                        }
                    }) {
                        Icon(imageVector = Icons.Filled.Menu, contentDescription = "")
                    }
                }
            )
        },
        scaffoldState = scaffoldState,
        drawerContent = {
            DrawerCompose(
                onDestinationClicked = { route ->
                    scope.launch {
                        scaffoldState.drawerState.close()
                    }
                },
               viewModel.onChangeEmpNo,
               viewModel.onChangePassword
            )
        },
        drawerGesturesEnabled = true
    ) {
        MenuList(
            loading = loading,
            menus = menuList,
            onNavigateToSubmenuScreen = onNavigateToMenuDetailScreen
        )
    }
}
  • Related