您可以使用
val state = rememberScrollState()
val lazyListState = rememberLazyListState()
LaunchedEffect(key1 = Unit) {
var oldValue = 0
snapshotFlow {
state.value
}.collect {
println("Value: $it")
lazyListState.scrollBy((it -oldValue).toFloat())
oldValue = it
}
}
当垂直滚动的列滚动时滚动 LazyColumn。
由于它不可重现或没有预期结果的图像,因此制作了一个示例来展示如何使用一个值进行滚动
@Preview
@Composable
private fun LayoutTest() {
val state = rememberScrollState()
val lazyListState = rememberLazyListState()
LaunchedEffect(key1 = Unit) {
var oldValue = 0
snapshotFlow {
state.value
}.collect {
println("Value: $it")
lazyListState.scrollBy((it - oldValue).toFloat())
oldValue = it
}
}
Column(
Modifier
.fillMaxSize()
.border(2.dp, Color.Red)
) {
Row(
Modifier
.fillMaxSize()
.border(3.dp, Color.Green)
) {
Column(
modifier = Modifier
.width(150.dp)
.fillMaxHeight()
.verticalScroll(state = state)
) {
for (i in 0..99) {
Text(
text = "Header $i",
fontSize = 20.sp,
color = Color.White,
modifier = Modifier
.fillMaxWidth()
.background(Color.Green)
)
}
}
LazyColumn(
modifier = Modifier
.fillMaxWidth(),
state = lazyListState
) {
items(100) {
Text(
text = "Row $it",
fontSize = 20.sp,
color = Color.White,
modifier = Modifier
.fillMaxWidth()
.background(Color.Red)
)
}
}
}
}
}
Edit
如果您希望同时滚动可滚动列和 LazyColumn,可以使用 NestedScrollConnection 获取 LazyColumn 的滚动值,并使用滚动 stat 来禁用侦听列滚动的 LaunchedEffect,以不再进一步滚动 LazyColumn。
但是,如果您在其他可组合项中的滚动正在进行时开始滚动,则此功能将无法正常工作。
@Preview
@Composable
private fun LayoutTest() {
val state = rememberScrollState()
val lazyListState = rememberLazyListState()
var listScrolling by remember {
mutableStateOf(false)
}
val coroutineScope = rememberCoroutineScope()
val nestedScrollConnection = remember {
object : NestedScrollConnection {
override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
val delta = -available.y
coroutineScope.launch {
state.scrollBy(delta)
listScrolling = true
}
return Offset.Zero
}
override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity {
listScrolling = false
return super.onPostFling(consumed, available)
}
}
}
LaunchedEffect(key1 = Unit) {
var oldValue = 0
snapshotFlow {
state.value
}.collect {
if (listScrolling.not() && lazyListState.isScrollInProgress.not()) {
lazyListState.scrollBy((it - oldValue).toFloat())
oldValue = it
}
}
}
Column(
Modifier
.fillMaxSize()
.padding(8.dp)
) {
Row(
Modifier
.fillMaxSize()
) {
Column(
modifier = Modifier
.width(150.dp)
.fillMaxHeight()
.verticalScroll(state = state)
) {
for (i in 0..400) {
Text(
text = "Header $i",
fontSize = 24.sp,
modifier = Modifier
.shadow(4.dp, RoundedCornerShape(8.dp))
.fillMaxWidth()
.background(Color.White, RoundedCornerShape(8.dp))
.padding(8.dp)
.wrapContentSize()
)
}
}
LazyColumn(
modifier = Modifier
.fillMaxWidth()
.nestedScroll(nestedScrollConnection),
state = lazyListState
) {
items(401) {
Text(
text = "Row $it",
fontSize = 24.sp,
modifier = Modifier
.shadow(4.dp, RoundedCornerShape(8.dp))
.fillMaxWidth()
.background(Color.White, RoundedCornerShape(8.dp))
.padding(8.dp)
.wrapContentSize()
)
}
}
}
}
}
Edit2
这个似乎在任何条件下都能很好地工作
@Preview
@Composable
private fun LayoutTest2() {
val state = rememberScrollState()
val lazyListState = rememberLazyListState()
val coroutineScope = rememberCoroutineScope()
val nestedScrollConnection = remember {
object : NestedScrollConnection {
override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
val delta = -available.y
if (state.isScrollInProgress.not()) {
coroutineScope.launch {
state.scrollBy(delta)
}
}
if (lazyListState.isScrollInProgress.not()) {
coroutineScope.launch {
lazyListState.scrollBy(delta)
}
}
return Offset.Zero
}
}
}
Column(
Modifier
.fillMaxSize()
.nestedScroll(nestedScrollConnection)
.padding(8.dp)
) {
Row(
Modifier
.fillMaxSize()
) {
Column(
modifier = Modifier
.width(150.dp)
.fillMaxHeight()
.verticalScroll(state = state)
) {
for (i in 0..400) {
Text(
text = "Header $i",
fontSize = 24.sp,
modifier = Modifier
.shadow(4.dp, RoundedCornerShape(8.dp))
.fillMaxWidth()
.background(Color.White, RoundedCornerShape(8.dp))
.padding(8.dp)
.wrapContentSize()
)
}
}
LazyColumn(
state = lazyListState,
modifier = Modifier
.fillMaxWidth()
) {
items(401) {
Text(
text = "Row $it",
fontSize = 24.sp,
modifier = Modifier
.shadow(4.dp, RoundedCornerShape(8.dp))
.fillMaxWidth()
.background(Color.White, RoundedCornerShape(8.dp))
.padding(8.dp)
.wrapContentSize()
)
}
}
}
}
}