Reputation: 53
I've a pager composed of cards and I want to control each card's border with a boolean variable: green if that variable's true, darkgrey else.
var isPedestrianSelected by remember { mutableStateOf(false) }
var isCyclistSelected by remember { mutableStateOf(false) }
var isCarSelected by remember { mutableStateOf(false) }
Card(
shape = RoundedCornerShape(70.dp),
border = BorderStroke(
1.2.dp,
when (page) {
0 -> { if (isPedestrianSelected) Color.Green else Color.DarkGray }
1 -> { if (isCarSelected) Color.Green else Color.DarkGray }
2 -> { if (isCyclistSelected) Color.Green else Color.DarkGray }
else -> { Color.DarkGray }
}
),
elevation = CardDefaults.cardElevation(
defaultElevation = 12.dp
),
onClick = {
val stationType = when (page) {
0 -> StationType.PEDESTRIAN
1 -> StationType.PASSENGER_CAR
2 -> StationType.CYCLIST
else -> { StationType.PEDESTRIAN }
}
when (stationType) {
StationType.PEDESTRIAN -> {
isPedestrianSelected = true
isCarSelected = false
isCyclistSelected = false
}
StationType.PASSENGER_CAR -> {
isPedestrianSelected = false
isCarSelected = true
isCyclistSelected = false
}
StationType.CYCLIST -> {
isPedestrianSelected = false
isCarSelected = false
isCyclistSelected = true
}
else -> {}
}
...
},
Issue: when the boolean variable (e.g. isCarSelected) is set to true, the borders are colored correctly (green), but when it returns to false, the borders won't change (although I'd expect they would change back to the darkgrey color).
Thanks for help
EDIT: Maybe I can explain better. My purpose is that at most one card of the pager has a green border, so what my code should do is, if I select one page, then put a green border around the card of that page and remove all green borders around cards of other pages. Example: isCarSelected = true, so the card on page 1 is set to a green border. After scrolling the pager, I click on another page, say page 0, and this sets isPedestrianSelected=true and other booleans to false, such as isCarSelected = false, and this should turn page 1 color from green to darkgray (along with turning page 0 color from darkgray to green). But this doesn't happen for some reason.
Upvotes: 1
Views: 117
Reputation: 950
The reason is in your onClick
function, you only ever set the target value to true and never to false.
This should work:
when (stationType) {
StationType.PEDESTRIAN -> {
isPedestrianSelected = if(isPedestrianSelected) false else true
isCarSelected = false
isCyclistSelected = false
}
StationType.PASSENGER_CAR -> {
isPedestrianSelected = false
isCarSelected = if(isCarSelected) false else true
isCyclistSelected = false
}
StationType.CYCLIST -> {
isPedestrianSelected = false
isCarSelected = false
isCyclistSelected = if(isCyclistSelected) false else true
}
else -> {}
}
However, I believe you could improve the code overall by maintaining one nullable mutable state which is updated on click where null represents none selected.
var selectedStationType: StationType? by remember { mutableStateOf(null) }
Upvotes: 0
Reputation: 10333
The problem with your current code is that you declare your isPedestrianSelected
/ isCarSelected
/ isCyclistSelected
variables within the content of the HorizontalPager
. So each page will have its own three local variables.
Move your declaration on top of the HorizontalPager
, then your code should work:
var isPedestrianSelected by remember { mutableStateOf(false) }
var isCyclistSelected by remember { mutableStateOf(false) }
var isCarSelected by remember { mutableStateOf(false) }
HorizontalPager(
// ...
) { page ->
Card(
//...
)
}
Note that you could simplify the logic of your implementation by instead using only one variable to store the index of the page where the card currently has a green border:
var selectedCardIndex by rememberSaveable { mutableStateOf(-1) }
HorizontalPager(
//...
) { page ->
Card(
shape = RoundedCornerShape(70.dp),
border = BorderStroke(
1.2.dp,
if (page == selectedCardIndex) Color.Green else Color.DarkGray
),
elevation = CardDefaults.cardElevation(
defaultElevation = 12.dp
),
onClick = {
selectedCardIndex = page
},
//...
)
}
Upvotes: 0