How to move DropdownMenu to preferable location in Jepack Compose - kotlin

Is it possible to center DropdownMenu in my example? or show it wherever I click or tap?
I tried alignment and arrangements and none of them work. I prefer showing the DropdownMenu wherever I tab but I couldn't find a way to do it.
fun main() = Window {
var helloText by remember { mutableStateOf("") }
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Item("Darian", "Russ") {
helloText = it
}
Item("Maynerd", "Andre") {
helloText = it
}
Item("Sandra", "Victoria") {
helloText = it
}
Spacer(modifier = Modifier.height(2.dp))
Text(text = helloText)
}
}
#Composable
fun Item(text: String, text2: String, onMenuTab: (String) -> Unit) {
var expanded by remember { mutableStateOf(false) }
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
val modifier = Modifier.clickable {
expanded = true
}
DropdownMenu(
expanded = expanded,
onDismissRequest = {
expanded = false
}
) {
DropdownMenuItem(onClick = {
onMenuTab("hello $text $text2")
expanded = false
}, modifier = Modifier.align(Alignment.CenterHorizontally)) {
Text("Hello")
}
DropdownMenuItem(onClick = { /* Handle settings! */ }) {
Text("Settings")
}
Divider()
DropdownMenuItem(onClick = { /* Handle send feedback! */ }) {
Text("Send Feedback")
}
}
Text(text = text, modifier = modifier)
Text(text = text2, modifier = modifier)
Divider(modifier = Modifier.height(2.dp))
Spacer(modifier = Modifier.height(2.dp))
}
}

For me fixing the alignment of the popup did the trick-
Popup(alignment = Alignment.TopStart)
Earlier it was Popup(alignment = Alignment.CenterStart)
and that was taking my popup view to the top of the screen. But now comes below the clicked item.

Related

Push Front View up with Keyboard, don't push Background View up in Kotlin Compose

I want to do something like this:
Where there is a view that pops on top of the open keyboard.
I've tried to do this, and I have this so far:
However, when I put this view in a Box, as the second view, the first view is also pushed up, here's the code:
#OptIn(ExperimentalFoundationApi::class, ExperimentalLayoutApi::class)
#ExperimentalComposeUiApi
fun Modifier.bringIntoViewAfterImeAnimation(): Modifier = composed {
var focusState by remember { mutableStateOf<FocusState?>(null) }
val relocationRequester = remember { BringIntoViewRequester() }
val isImeVisible = WindowInsets.isImeVisible
LaunchedEffect(
isImeVisible,
focusState,
relocationRequester
) {
if (isImeVisible && focusState?.isFocused == false) {
relocationRequester.bringIntoView()
}
relocationRequester.bringIntoView()
}
bringIntoViewRequester(relocationRequester).onFocusChanged { focusState = it }
}
#OptIn(ExperimentalComposeUiApi::class)
#Composable
fun SpaceCreator(navController: NavController) {
Column(
modifier = Modifier.fillMaxSize().clip(RoundedCornerShape(10.dp)),
verticalArrangement = Arrangement.Bottom
) {
SpaceCreatorContainer()
}
}
#OptIn(ExperimentalComposeUiApi::class)
#Composable
fun SpaceCreatorContainer() {
Card(
modifier = Modifier
.bringIntoViewAfterImeAnimation()
.shadow(elevation = 10.dp, shape = RoundedCornerShape(10.dp), clip = true)
.background(color = colors.background)
) {
SpaceCreatorWrapper()
}
}
#Composable
fun SpaceCreatorWrapper() {
val localFocusManager = LocalFocusManager.current
Column(
modifier = Modifier.padding(15.dp).clip(RoundedCornerShape(10.dp))
) {
Text(
modifier = Modifier.fillMaxWidth(),
text = "Top Text"
)
Text(text = "Content")
OutlinedTextField(
value = "ss",
onValueChange = { },
label = { Text("Email Address") },
singleLine = true,
modifier = Modifier.fillMaxWidth(),
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Email,
imeAction = ImeAction.Done,
),
keyboardActions = KeyboardActions(
onDone = { localFocusManager.clearFocus() }
)
)
OutlinedTextField(
value = "ss",
onValueChange = { },
label = { Text("Email Address") },
singleLine = true,
modifier = Modifier.fillMaxWidth(),
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Email,
imeAction = ImeAction.Done
),
keyboardActions = KeyboardActions(
onDone = { localFocusManager.clearFocus() }
)
)
Text(text = "Content")
}
}
That's the code for SpaceCreator(), and then I add it to a Box where it's supposed to float over another view, like so:
BoxWithConstraints(
propagateMinConstraints = true
) {
Box(
modifier = Modifier
.fillMaxSize()
) {
MainView()
SpaceCreator(navController = navController)
}
}
How do I only push up the second view in the Box when the keyboard is opened, and not the entire box?
Also,
Currently, I have a AnimationNavigation screen which is a Box(fillMaxSize), and the content of the keyboard modal stuck to the bottom. I also have a auto focus on the input, which is making the navigation a bit slow, unlike other apps I've seen.
Is there a smooth way to do this on low-mid-range devices like Samsung A23?
Thank you.

Jetpack Compose: How to show Alert Dialog with a single item's information from LazyColumn clicked item?

I'm working on a simple project where I import a database of inventory items with room and can modify inventory according to changes. I'm struggling with the LazyColumn.
What I need: When an item from LazyColumn is clicked, show alert dialog with item info.
What happens: When an item from LazyColumn is clicked, it shows all the items alert dialog (generates 100+ alert dialogs and only the last one is visible).
Application Main page with LazyColumn:
After clicking on item shows huge shadow of 100+ Alert dialogs and only the last item is visible:
//custom alert dialog taking parameters from the database class of the inventory items
#Composable
fun ItemAlertDialog(
onDismiss: () -> Unit,
onNegativeClick: () -> Unit,
onPositiveClick: () -> Unit,
currentInventory: Int,
itemDescription: String,
itemNumber: String,
) {
var incoming by remember { mutableStateOf(0f) }
var outgoing by remember { mutableStateOf(0f) }
Dialog(onDismissRequest = onDismiss) {
Card(
elevation = 8.dp,
shape = RoundedCornerShape(12.dp)
) {
Column(modifier = Modifier.padding(8.dp)) {
Text(
text = itemNumber,
fontWeight = FontWeight.Bold,
fontSize = 20.sp,
modifier = Modifier.padding(8.dp)
)
Spacer(modifier = Modifier.height(8.dp))
Text(
text = itemDescription,
fontWeight = FontWeight.Normal,
fontSize = 15.sp,
modifier = Modifier.padding(8.dp)
)
Spacer(modifier = Modifier.height(8.dp))
Text(
text = currentInventory.toString(),
fontWeight = FontWeight.ExtraBold,
color = Color(0xFF0FFC107),
fontSize = 20.sp,
modifier = Modifier.padding(8.dp)
)
// Update Inventory
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
) {
Column {
Text(text = "Incoming ${incoming.toInt()}")
Slider(
value = incoming,
onValueChange = { incoming = it },
valueRange = 0f..100f,
onValueChangeFinished = {}
)
Spacer(modifier = Modifier.height(8.dp))
Text(text = "Outgoing ${outgoing.toInt()}")
Slider(
value = outgoing,
onValueChange = { outgoing = it },
valueRange = 0f..100f,
onValueChangeFinished = {}
)
}
}
// Buttons
Row(
horizontalArrangement = Arrangement.End,
modifier = Modifier.fillMaxWidth()
) {
TextButton(onClick = onNegativeClick) {
Text(text = "CANCEL")
}
Spacer(modifier = Modifier.width(4.dp))
TextButton(onClick = {
onPositiveClick.invoke()
}) {
Text(text = "OK")
}
}
}
}
}
}
Items row code with the onclick I want to fire the dialog with:
#Composable
fun MainScreenItemRow(
itemNumber: String,
itemDescription: String,
currentInventory: Int,
onclick: () -> Unit
) {
Row(modifier = Modifier
.clickable {
onclick.invoke()
}
.border(width = 1.dp, color = Color.Gray, shape = RoundedCornerShape(8.dp))
.padding(16.dp)
.clip(shape = RoundedCornerShape(8.dp)),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = itemNumber,
fontSize = 12.sp,
fontWeight = FontWeight.Bold,
modifier = Modifier.weight(3f)
)
Spacer(modifier = Modifier.width(10.dp))
Text(
text = itemDescription,
fontSize = 12.sp,
maxLines = 3,
modifier = Modifier.weight(4f)
)
Spacer(modifier = Modifier.width(30.dp))
Text(
text = currentInventory.toString(),
fontSize = 20.sp,
color = Color(0xFF0FFC107),
modifier = Modifier.weight(1f)
)
}
}
MainActivity code (apologies for messy code, notes annotated with //***):
#AndroidEntryPoint
class MainActivity : ComponentActivity() {
private val mainViewModel: MainViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val systemUiController = rememberSystemUiController()
val useDarkIcons = MaterialTheme.colors.isLight
val inventoryList by mainViewModel.getInventoryItems.collectAsState(initial = emptyList())
val showItemDialog = remember { mutableStateOf(false)}
val result = remember { mutableStateOf("") }
val expanded = remember { mutableStateOf(false) }
val randomList = listOf("")
val selectedItem = remember{ mutableStateOf(randomList[0])}
//*** getting inventoryList from the flow, added remember to selectedItem and showItemDialog
SimpleInventoryTheme {
ItemModelDrawer{drawerState, drawerScopeState ->
SideEffect {
systemUiController.setSystemBarsColor(
color = Color.Transparent,
darkIcons = useDarkIcons
)
}
Scaffold(
topBar = {
TopAppBar(
title = {
Text(text = "Inventory Manager")
},
actions = {
IconButton(onClick = {
drawerScopeState.launch {
drawerState.open()
}
}) {
Icon(Icons.Outlined.Search, contentDescription = "Search")
}
Box(
Modifier
.wrapContentSize(Alignment.TopEnd)
) {
IconButton(onClick = {
expanded.value = true
result.value = "More icon clicked"
}) {
Icon(
Icons.Filled.MoreVert,
contentDescription = "Localized description"
)
}
DropdownMenu(
expanded = expanded.value,
onDismissRequest = { expanded.value = false },
) {
DropdownMenuItem(onClick = {
expanded.value = false
result.value = "First item clicked"
}) {
Text("First Item")
}
Divider()
DropdownMenuItem(onClick = {
expanded.value = false
result.value = "Second item clicked"
}) {
Text("Second item")
}
}
}
},
backgroundColor = Color.White,
elevation = AppBarDefaults.TopAppBarElevation
)
},
content = {
Column(modifier = Modifier.fillMaxSize()) {
MainScreenTitlesRow()
Divider()
//*** Showing the items in the main page and adding onclick to fire up the alert dialog
LazyColumn(
verticalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier
.fillMaxSize()
.padding(16.dp)
) {
itemsIndexed(inventoryList) { idx, item ->
item.currentInventory?.let {
MainScreenItemRow(
itemNumber = item.itemNumber,
itemDescription = item.itemDescription,
currentInventory = it,
onclick = {
//*** trying to set the clicked item into "selectedItem" val
selectedItem.value = item.itemNumber
selectedItem.value = item.itemDescription
selectedItem.value = item.currentInventory.toString()
Log.d("MainActivityItemClicked", "$selectedItem ")
showItemDialog.value = true
}
)
}
}
}
//*** Trying to check which item was clicked and only present its information in the alert dialog but it loads up all the items
if (showItemDialog.value) {
LazyColumn {
itemsIndexed(inventoryList) { _, item ->
item.currentInventory?.let {
ItemAlertDialog(
itemNumber = item.itemNumber,
itemDescription = item.itemDescription,
currentInventory = it,
onDismiss = {
showItemDialog.value = !showItemDialog.value
Toast.makeText(
this#MainActivity,
"Dialog dismissed!",
Toast.LENGTH_SHORT
)
.show()
},
onNegativeClick = {
showItemDialog.value = !showItemDialog.value
Toast.makeText(
this#MainActivity,
"Cancel!",
Toast.LENGTH_SHORT
)
.show()
},
onPositiveClick = {
showItemDialog.value = !showItemDialog.value
Toast.makeText(
this#MainActivity,
"Saved!",
Toast.LENGTH_SHORT
)
.show()
}
)
}
}
}
}
}
}
)
}
}
}
}
}
Thank you #Philip Dukhov
I've tried doing this previously and couldn't get the item.Number, item.description, item.inventory at all (val not resolved) so used the inventoryList since I could get it at least smething which was the wrong approach per your suggestion.
I learned a thing or two in the last few days struggling, so with your tip I managed to achive what I need. Not sure it's the right way but it works now. On to the next struggle!
//***Modified the selected Item from val selectedItem = remember{ mutableStateOf(randomList[0])} to separate 3:
val selectedItemNumber = remember{ mutableStateOf(randomList[0])}
val selectedItemDescription = remember{ mutableStateOf(randomList[0])}
val selectedItemInventory = remember{ mutableStateOf(randomList[0])}
LazyColumn(
verticalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier
.fillMaxSize()
.padding(16.dp)
) {
itemsIndexed(inventoryList) { idx, item ->
item.currentInventory?.let {
MainScreenItemRow(
itemNumber = item.itemNumber,
itemDescription = item.itemDescription,
currentInventory = it,
onclick = {
selectedItemNumber.value = item.itemNumber
selectedItemDescription.value = item.itemDescription
selectedItemInventory.value = item.currentInventory.toString()
Log.d("MainActivityItemClicked", "$selectedItemDescription ")
showItemDialog.value = true
}
)
}
}
}
if (showItemDialog.value) {
ItemAlertDialog(
itemNumber = selectedItemNumber.value,
itemDescription = selectedItemDescription.value,
currentInventory = selectedItemInventory.value.toInt(),
onDismiss = {
showItemDialog.value = !showItemDialog.value
Toast.makeText(
this#MainActivity,
"Dialog dismissed!",
Toast.LENGTH_SHORT
)
.show()
},
onNegativeClick = {
showItemDialog.value = !showItemDialog.value
Toast.makeText(
this#MainActivity,
"Cancel!",
Toast.LENGTH_SHORT
)
.show()
},
onPositiveClick = {
showItemDialog.value = !showItemDialog.value
Toast.makeText(
this#MainActivity,
"Saved!",
Toast.LENGTH_SHORT
)
.show()
}
)
}
}

Clickable Toggle Continuously Repeating Causing UI Glitch in Search Bar - Jetpack Compose Android Studio Kotlin

I'm trying to have the text field appear when the "Search Movies" button is selected, and disappear when not selected.
When I tap on the "Search Movies" button, the app seems to recognize the clicks constantly.
Here's a video of what it looks like: https://youtu.be/5LQ8k0Y05Cc
As you can see, the text field also doesn't disappear when the "Popular Movies" button is selected.
Here's the composable function:
#Composable
fun MaterialButtonToggleGroup() {
val options = listOf(
"Popular Movies",
"Search Movies"
)
var selectedOption by remember {
mutableStateOf("")
}
val onSelectionChange = { text: String ->
selectedOption = text
}
Column() {
var isExpanded by remember { mutableStateOf(false) }
Row(
horizontalArrangement = Arrangement.SpaceEvenly,
modifier = Modifier.fillMaxWidth(),
) {
options.forEach { text ->
Row(
modifier = Modifier
.padding(
vertical = 8.dp,
),
) {
Text(
text = text,
style = typography.body1.merge(),
color = Color.White,
modifier = Modifier
.clip(
shape = RoundedCornerShape(
size = 12.dp,
),
)
.clickable {
onSelectionChange(text)
}
.background(
if (text == selectedOption) {
Color.Magenta
} else {
Color.Gray
}
)
.padding(
vertical = 12.dp,
horizontal = 16.dp,
),
)
}
}
}
if (selectedOption == "Search Movies") {
isExpanded = !isExpanded
}
if (isExpanded) {
var text by remember { mutableStateOf("") }
OutlinedTextField(
value = text,
modifier = Modifier.fillMaxWidth()
.padding(all = 3.dp),
onValueChange = { text = it },
label = { Text("Enter Movie Info") }
)
}
}
(activity as MainActivity?)?.viewSelection(selectedOption)
}
Surface {
MaterialButtonToggleGroup()
}
Turns out I should just set isExpanded to true or false for each scenario.
I changed:
if (selectedOption == "Search Movies") {
isExpanded = !isExpanded
}
if (isExpanded) {
var text by remember { mutableStateOf("") }
OutlinedTextField(
value = text,
modifier = Modifier.fillMaxWidth()
.padding(all = 3.dp),
onValueChange = { text = it },
label = { Text("Enter Movie Info") }
)
}
To:
if (selectedOption == "Search Movies") {
isExpanded = true
} else {
isExpanded = false
}
if (isExpanded) {
var text by remember { mutableStateOf("") }
OutlinedTextField(
value = text,
modifier = Modifier
.fillMaxWidth()
.padding(all = 3.dp),
onValueChange = { text = it },
label = { Text("Enter Movie Info") }
)
}

Jetpack Compose - Disable TextField long press handler

I have an IconButton in the trailingIcon of OutlinedTextField like:
OutlinedTextField(
modifier = Modifier.weight(1f),
label = { Text(text = "Label") },
value = text,
onValueChange = { text = it },
trailingIcon = {
IconButton2(onClick = {
println("onClick")
}, onLongClick = {
println("onLongClick shows TextToolbar")
}) {
Icon(
imageVector = Icons.Filled.Menu,
contentDescription = null
)
}
}
)
IconButton2 is just a copy of IconButton but with combinedClickable to include onLongClick instead of clickable.
The problem is that when I long click IconButton2, it shows the TextToolbar for the TextField. Doesn't matter what I do, the text field will handle long click, show the TextToolbar and provide haptic feedback.
Even if I use pointerInput with awaitPointerEvent and consumeAllChanges (like here) it still triggers it. The TextField doesn't answer to any tap or anything but if I long click it, it answers!
The workaround I'm doing for now is wrapping the text field in a Row and add the IconButton beside it instead of "inside" but I needed to have the icon button as the trailingIcon.
Is there any way to properly do it?
Compose 1.0.3 and 1.1.0-alpha05 both behaves the same.
I ended up making a small hack that seems to be working fine, so basically I add a dummy Box as the trailingIcon to get the position of it, then I add an IconButton outside of it (both wrapped in a Box) and I also get the position of it + I offset it using the position of the dummy box. Not the ideal solution but works fine.
Here's the full source if anyone needs it:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyApplicationTheme {
Surface(
modifier = Modifier.padding(16.dp),
color = MaterialTheme.colors.background
) {
var text by remember { mutableStateOf("") }
var trailingIconOffset by remember { mutableStateOf(Offset.Zero) }
var iconButtonOffset by remember { mutableStateOf(Offset.Zero) }
val colors = TextFieldDefaults.outlinedTextFieldColors()
Column {
//With hack
Box {
OutlinedTextField(
modifier = Modifier.fillMaxWidth(),
label = { Text(text = "With hack") },
value = text,
onValueChange = { text = it },
trailingIcon = {
Box(modifier = IconButtonSizeModifier
.onGloballyPositioned {
trailingIconOffset = it.positionInRoot()
}
)
},
colors = colors
)
val contentColor by colors.trailingIconColor(
enabled = true,
isError = false
)
CompositionLocalProvider(
LocalContentColor provides contentColor,
LocalContentAlpha provides contentColor.alpha
) {
IconButton2(
modifier = Modifier
.onGloballyPositioned {
iconButtonOffset = it.positionInRoot()
}
.absoluteOffset {
IntOffset(
(trailingIconOffset.x - iconButtonOffset.x).toInt(),
(trailingIconOffset.y - iconButtonOffset.y).toInt()
)
},
onClick = {
text = "onClick"
},
onLongClick = {
text = "onLongClick"
}
) {
Icon(imageVector = Icons.Filled.Menu, contentDescription = null)
}
}
}
//Without hack
Box {
OutlinedTextField(
modifier = Modifier.fillMaxWidth(),
label = { Text(text = "Without hack") },
value = text,
onValueChange = { text = it },
trailingIcon = {
IconButton2(
onClick = {
text = "onClick"
},
onLongClick = {
text = "onLongClick"
}
) {
Icon(
imageVector = Icons.Filled.Menu,
contentDescription = null
)
}
},
colors = colors
)
}
}
}
}
}
}
}
private val RippleRadius = 24.dp
private val IconButtonSizeModifier = Modifier.size(48.dp)
#OptIn(ExperimentalFoundationApi::class)
#Composable
fun IconButton2(
modifier: Modifier = Modifier,
onClick: () -> Unit,
onLongClick: (() -> Unit)? = null,
enabled: Boolean = true,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
content: #Composable () -> Unit
) {
Box(
modifier = modifier
.combinedClickable(
onClick = onClick,
onLongClick = onLongClick,
enabled = enabled,
role = Role.Button,
interactionSource = interactionSource,
indication = rememberRipple(bounded = false, radius = RippleRadius)
)
.then(IconButtonSizeModifier),
contentAlignment = Alignment.Center
) {
val contentAlpha = if (enabled) LocalContentAlpha.current else ContentAlpha.disabled
CompositionLocalProvider(LocalContentAlpha provides contentAlpha, content = content)
}
}

Navigation in Jetpack Compose

I am working on this shopping app which uses radio buttons. The customer should be able to select a radio button and go it by clicking the 'select button'.
Can anyone help me get get started.
the code is below.
I hope this makes sense to everyone. I have made a page for each of the radio buttons. pages are name the same as the buttons.
#Composable
fun MyRadioGroup() {
val navController = rememberNavController()
val radioOptions = listOf(
"Dollar Store", "Fred Myers",
"Wall Mart", "SafeWay", "Sherm's", "CostCo", "Other"
)
val (selectedOption, onOptionSelected) = remember {
mutableStateOf(radioOptions[1])
}
Scaffold() {
TopAppBar(
title = { Text(stringResource(id = R.string.app_name)) },
)
}
Column(
modifier = Modifier
.padding(start = 16.dp, top = 160.dp)
) {
Text(
text = "Select Store from List Below")
Divider()
Text(
text = "Then push the 'Select'")
}
Column(
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
) {
radioOptions.forEach { text ->
Row(
Modifier
.fillMaxWidth()
.padding(top = 8.dp)
.selectable(
selected = (text == selectedOption),
onClick = { onOptionSelected(text) }
)
.padding(horizontal = 16.dp)
) {
RadioButton(
selected = (text == selectedOption),
modifier = Modifier
.padding(start = 16.dp, top = 12.dp),
onClick = {
onOptionSelected(text)
}
)
Text(
text = text,
modifier = Modifier.padding(start = 16.dp, top = 16.dp)
)
}
}
}
Column(modifier = Modifier
.padding(start = 24.dp, top = 640.dp)
) {
Button(onClick = {
TODO()
}) {
Text(text = "Select")
}
}
}
The 'select' button is near the bottom of the code.
First create a sealed class Screen to link radio buttons text to composable as recommended by Google like this:
sealed class Screen(val route: String, val label: String){
object MyRadioGroup: Screen(route = "myRadioGroup", label = "APP NAME")
object DollarStore: Screen(route = "Dollar Store", label = "Dollar Store")
object FreedMyers: Screen(route = "Fred Myers", label = "FreedMyers")}
then modify NavHost or AnimatedNavHost(if you are using accompanist's Navigatio Animatation library as:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val navController = rememberNavController()
Surface(color = MaterialTheme.colors.background) {
NavHost(navController = navController, startDestination = Screen.MyRadioGroup.route){
composable(Screen.MyRadioGroup.route){
MyRadioGroup(navController = navController)
}
composable(Screen.DollarStore.route){
//Call here the associated composable function
DollarStore()
}
composable(Screen.FreedMyers.route){
//Call here the associated composable function
FreedMyers()
}
}
}
}
}}
Finally add some code to MyRadioGroup Composable
fun MyRadioGroup(navController: NavController) {
val radioOptions = listOf(
"Dollar Store", "Fred Myers",
"Wall Mart", "SafeWay", "Sherm's", "CostCo", "Other"
)
val (selectedOption, onOptionSelected) = remember {
mutableStateOf(radioOptions[1])
}
Scaffold(
topBar = {
TopAppBar(
title = { Text(stringResource(id = R.string.app_name)) },
)
}
) {
Column(modifier = Modifier.verticalScroll(rememberScrollState())) {
Column(
modifier = Modifier.padding(start = 16.dp, top = 16.dp)
) {
Text(text = "Select Store from List Below")
Divider()
Text(text = "Then push the 'Select'")
}
Column(
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
) {
radioOptions.forEach { text ->
Row(
Modifier
.fillMaxWidth()
.padding(top = 8.dp)
.selectable(
selected = (text == selectedOption),
onClick = { onOptionSelected(text) }
)
.padding(horizontal = 16.dp)
) {
RadioButton(
selected = (text == selectedOption),
modifier = Modifier
.padding(start = 16.dp, top = 12.dp),
onClick = { onOptionSelected(text) }
)
Text(
text = text,
modifier = Modifier.padding(start = 16.dp, top = 16.dp)
)
}
}
}
Column(
modifier = Modifier
.padding(start = 24.dp, top = 24.dp)
) {
Button(
onClick = {
navController.navigate(selectedOption) //navigate to selected route
}
) {
Text(text = "Select")
}
}
}
}}