Olhm.exe
Olhm.exe

Reputation: 5

Android Jetpack Compose: Data Passing to Another Composable Using Navigation

I have an issue regarding the transmission of data generated during user interaction with the TextField, 'StatsField'. I would like the value entered in these fields to be reassigned in another activity. The solution I found is to use data transmission via Compose navigation arguments.

Unfortunately, only the composable function 'CharacterSkillScreen' is able to use its data. However, I need it in the composable 'ItemSkillView'.

I don't think it's complicated, but I've been going around in circles for a few days...

I've only been programming for Android for a few months. This application is a learning project. In fact, it's also the first time I've used StackOverFlow.

Hoping that I will have some answers.

The relevant code:

CharacterScreen.kt:

 ClickableBox(
            icon = painterResource(R.drawable.ic_skill3),
            subtitle = "COMPÉTENCES",
            onClick = {
                navController.navigate(Screen.CharacterSkillScreen
                    .withArgs(
                        characterUiState.strenght,
                        characterUiState.dexterity,
                        characterUiState.constitution,
                        characterUiState.intelligence,
                        characterUiState.wisdom,
                        characterUiState.charism
                    )
                )
            }
        )

CharacterSkillScreen.kt:

@Composable
fun CharacterSkillScreen(
    strenghtValue: String? = "",
    dexterityValue: String? = "",
    constitutionValue: String? = "",
    intelligenceValue: String? = "",
    wisdomValue: String? = "",
    charismValue: String? = "",
    skillViewModel: SkillViewModel = viewModel()
) {
    val addedSkill = remember { mutableStateListOf<@Composable () -> Unit>() }
    val skillUiState by skillViewModel.uiState.collectAsState()

    Column {
        Row(modifier = Modifier.padding(20.dp)) {
            val statsField = listOf(
                "FOR" to strenghtValue,
                "DEX" to dexterityValue,
                "CON" to constitutionValue,
                "INT" to intelligenceValue,
                "SAG" to wisdomValue,
                "CHA" to charismValue
            )
            statsField.forEach { (label, value) ->
                StatsField(
                    label = label,
                    value = value.toString(),
                    onValueChange = {
                        skillViewModel.updateStrenghtValue(it)
                    },
                    modifier = Modifier.weight(1f)
                )
            }
        }
        Divider(thickness = 1.dp, color = Color.Black)
        LazyColumn(
            modifier = Modifier.fillMaxWidth(),
            horizontalAlignment = Alignment.CenterHorizontally
        ){
            items(addedSkill) {skillItemList ->
                skillItemList()
                Divider(thickness = 1.dp, color = Color.Black)
            }
            item {
                Button(
                    modifier = Modifier.padding(top = 10.dp),
                    onClick = {
                        addedSkill.add { ItemSkillView() }
                    }
                ) {
                    Text("Ajouter une compétence")
                }
            }
        }
        Text(text = "Force renvoit : ${skillUiState.strenght}")
    }
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ItemSkillView(
    skillViewModel: SkillViewModel = viewModel(),
    resultActionPoints: String = "0"
) {
    val uiState by skillViewModel.uiState.collectAsState()
    var isExpanded by remember { mutableStateOf(false) }

    Column(
        modifier = Modifier
            .fillMaxWidth()
            .clickable { isExpanded = !isExpanded }
            .animateContentSize()
    ) {
        ConstraintLayout(modifier = Modifier.fillMaxWidth()) {
            val (icon, skill, resultSkill) = createRefs()

            Icon(
                painter = painterResource(id = R.drawable.expand_more),
                contentDescription = "Expanded button",
                tint = Color.Black,
                modifier = Modifier
                    .size(40.dp)
                    .constrainAs(icon) {
                        start.linkTo(parent.start, margin = 10.dp)
                        top.linkTo(skill.top)
                        bottom.linkTo(skill.bottom)
                    }
            )
            TextField(
                value = uiState.skillTitle,
                onValueChange = { newValue ->
                    skillViewModel.updateSkillTitle(newValue)
                },
                label = { Text(text = "NOM DE LA COMPÉTENCE ") },
                colors = TextFieldDefaults.outlinedTextFieldColors(
                    focusedBorderColor = Color.Transparent,
                    unfocusedBorderColor = Color.Transparent
                ),
                modifier = Modifier.constrainAs(skill) {
                    start.linkTo(icon.end)
                    end.linkTo(resultSkill.start)
                }
            )
            Text(
                text = resultActionPoints,
                fontSize = 16.sp,
                textAlign = TextAlign.Center,
                modifier = Modifier
                    .border(1.dp, Color.Black)
                    .padding(top = 3.dp, bottom = 3.dp)
                    .constrainAs(resultSkill) {
                        start.linkTo(skill.end, margin = 18.dp)
                        end.linkTo(parent.end, margin = 18.dp)
                        top.linkTo(skill.top)
                        bottom.linkTo(skill.bottom)
                        width = Dimension.fillToConstraints
                    }
            )
        }
        if(isExpanded) {
            ExposedDropDownMenuSkill()
        }
    }
}

My code's GitHub: https://github.com/Olhm/2D6_One_One_Versus_System.git

I tried to access the data of the text field in 'StatsField' via my 'CharacterViewModel' but, on the skills page, 'characterUiState.dexterity', 'characterUiState.constitution'... do not return any value.

Upvotes: 0

Views: 4016

Answers (1)

NewPartizal
NewPartizal

Reputation: 1124

If you want to move data between activities you can use parcelize

for example like this:

Pass Parcelable argument with compose navigation

Upvotes: 1

Related Questions