Skip to content

Instantly share code, notes, and snippets.

@slaviboy
Last active September 9, 2023 16:55
Show Gist options
  • Save slaviboy/43bb52db000b691a5b4dac3c440703d7 to your computer and use it in GitHub Desktop.
Save slaviboy/43bb52db000b691a5b4dac3c440703d7 to your computer and use it in GitHub Desktop.
How to position selected element at the middle of a Row
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