Last active
September 9, 2023 16:55
-
-
Save slaviboy/43bb52db000b691a5b4dac3c440703d7 to your computer and use it in GitHub Desktop.
How to position selected element at the middle of a Row
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.slaviboy.test | |
import android.os.Bundle | |
import androidx.activity.ComponentActivity | |
import androidx.activity.compose.setContent | |
import androidx.compose.foundation.clickable | |
import androidx.compose.foundation.horizontalScroll | |
import androidx.compose.foundation.layout.Arrangement | |
import androidx.compose.foundation.layout.Row | |
import androidx.compose.foundation.layout.padding | |
import androidx.compose.foundation.layout.width | |
import androidx.compose.foundation.layout.wrapContentHeight | |
import androidx.compose.foundation.rememberScrollState | |
import androidx.compose.material3.Text | |
import androidx.compose.runtime.Composable | |
import androidx.compose.runtime.LaunchedEffect | |
import androidx.compose.runtime.getValue | |
import androidx.compose.runtime.mutableStateListOf | |
import androidx.compose.runtime.mutableStateOf | |
import androidx.compose.runtime.remember | |
import androidx.compose.runtime.rememberCoroutineScope | |
import androidx.compose.runtime.setValue | |
import androidx.compose.ui.Alignment | |
import androidx.compose.ui.Modifier | |
import androidx.compose.ui.graphics.Color | |
import androidx.compose.ui.layout.onGloballyPositioned | |
import androidx.compose.ui.layout.positionInParent | |
import androidx.compose.ui.platform.LocalDensity | |
import androidx.compose.ui.unit.dp | |
import androidx.compose.ui.unit.sp | |
import kotlinx.coroutines.launch | |
import kotlin.math.roundToInt | |
class MainActivity : ComponentActivity() { | |
override fun onCreate(savedInstanceState: Bundle?) { | |
super.onCreate(savedInstanceState) | |
setContent { | |
Test() | |
} | |
} | |
} | |
data class Balance( | |
val amount: String, | |
val isSelected: Boolean | |
) | |
@Composable | |
fun Test() { | |
val scope = rememberCoroutineScope() | |
val scrollState = rememberScrollState() | |
val list = remember { | |
mutableStateListOf( | |
Balance("$342.23", false), | |
Balance("€23,342.23", false), | |
Balance("£9,934.30", false), | |
Balance("BGN 543.43", false), | |
Balance("BLR 43.35", true), | |
Balance("HUN 492.35", false), | |
Balance("JPY 5326", false) | |
) | |
} | |
var selectionFlag by remember { | |
mutableStateOf(true) | |
} | |
var scrollToPosition by remember { | |
mutableStateOf(0f) | |
} | |
LaunchedEffect(selectionFlag) { | |
scope.launch { | |
scrollState.animateScrollTo(scrollToPosition.roundToInt()) | |
} | |
} | |
val paddingHorizontal = 50.dp | |
val paddingHorizontalPx = with(LocalDensity.current) { paddingHorizontal.toPx() } | |
val parentWidth = 400.dp | |
val parentWidthPx = with(LocalDensity.current) { parentWidth.toPx() } | |
Row( | |
horizontalArrangement = Arrangement.Center, | |
verticalAlignment = Alignment.Bottom, | |
modifier = Modifier | |
.padding(horizontal = paddingHorizontal) | |
.width(parentWidth) | |
.wrapContentHeight() | |
.horizontalScroll(scrollState) | |
) { | |
list.forEachIndexed { i, item -> | |
val (amount, isSelected) = item | |
Text( | |
text = amount, | |
color = if (isSelected) { | |
Color.Red | |
} else { | |
Color.Red.copy( | |
alpha = 0.2f | |
) | |
}, | |
fontSize = 15.sp, | |
modifier = Modifier | |
.padding( | |
horizontal = 10.dp | |
) | |
.onGloballyPositioned { coordinates -> | |
if (isSelected) { | |
val x = coordinates.positionInParent().x | |
val width = coordinates.size.width | |
scrollToPosition = x - (parentWidthPx / 2f) + paddingHorizontalPx + (width / 2f) | |
} | |
} | |
.clickable { | |
val selectedIndex = list.indexOfFirst { it.isSelected } | |
list[i] = list[i].copy(isSelected = true) | |
list[selectedIndex] = list[selectedIndex].copy(isSelected = false) | |
selectionFlag = !selectionFlag | |
} | |
) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment