首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >LazyColumn animateScrollBy什么都不做?

LazyColumn animateScrollBy什么都不做?
EN

Stack Overflow用户
提问于 2022-04-04 20:40:14
回答 1查看 476关注 0票数 0

更新:最初的问题,然后是更新的示例代码,根据请求触发它。

我在一张懒散的单子里列出了半个小时的时间。

12:00,12:30

该列表附加在伴奏寻呼机库的水平寻呼机上。

当用户在页面之间滑动时,我需要更新所选的时间,如果不靠近顶部/底部,我希望选择的时间始终位于屏幕的中心。

我想出了如何用提供给我们的方法精确地完成这个任务的唯一方法是如下所示。

注意:我之前已经捕获了按钮/列表高度。

代码语言:javascript
运行
复制
  val listState = rememberLazyListState()

  LaunchedEffect(pagerState) {
            snapshotFlow { pagerState.currentPage }.collect { page ->
                if (page != selectedPage) {
                    listState.scrollToItem(0) //Need to be at the top for calc below to work
                    listState.scrollBy(buttonHeight.toFloat() * page - (listVisibleHeight / 2) + buttonHeight)
                }
            }
        } 

这件事做得很好。当我从00:00开始并向下移动列表时,直到我到达中间,并且一旦我到达中间,所选的时间就会随着时间的滚动而停留在中间,并且一直在中间,直到我接近列表的末尾,它开始向下移动。

现在还有一种方法listState.animateScrollBy(float, animation)很理想,如果你点击了一些不是在中间的东西,它必须把它放回中间,但是当我使用这个方法的时候,绝对不会发生什么事情?

代码语言:javascript
运行
复制
   listState.animateScrollBy(buttonHeight.toFloat() * page - (listVisibleHeight / 2) + buttonHeight)

对我来说就像被打破了一样?好像我从来没有调用过这个函数。0滚动,即使当我尝试添加一个非默认动画。我在这里做错什么了吗?

它是在编写1.2.0-字母04和1.2.0-字母06时这样做的。

我可以继续使用scrollBy,但是没有动画,如果用户点击一个时间而不是滑动到一个时间,它会有点不稳定。

现在我知道为什么它是按要求发生的

寻呼机的特殊进口产品

代码语言:javascript
运行
复制
  implementation "com.google.accompanist:accompanist-pager:0.24.5-alpha"
  implementation "com.google.accompanist:accompanist-pager-indicators:0.24.5-alpha"

注意:寻呼机本身一直不稳定,因为我更新了它,以修复一个较早版本的崩溃.它不太正确,它有时会被卡住。不过,我还没有对此进行调查。

代码语言:javascript
运行
复制
import android.util.Log
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.animateScrollBy
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.onGloballyPositioned
import com.google.accompanist.pager.ExperimentalPagerApi
import com.google.accompanist.pager.HorizontalPager
import com.google.accompanist.pager.PagerState

@ExperimentalPagerApi
@Composable
fun TestScreen() {
    val numberOfRows = 48

    val listState = rememberLazyListState()
    var selectedRow by remember { mutableStateOf(0) }
    var buttonHeight by remember { mutableStateOf(0) }
    var listVisibleHeight by remember { mutableStateOf(0) }
    val pagerState = PagerState(currentPage = selectedRow)

    Row(
        modifier = Modifier
            .onGloballyPositioned {
                listVisibleHeight = it.size.height
            }
    ) {
        LazyColumn(
            state = listState,
            modifier = Modifier
                .wrapContentSize(),
            horizontalAlignment = Alignment.CenterHorizontally,
        ) {
            items(numberOfRows) { index ->
                Button(
                    modifier = Modifier
                        .wrapContentWidth()
                        .onGloballyPositioned {
                            buttonHeight = it.size.height
                        },
                    onClick = {}
                ) {
                    if (index == selectedRow) {
                        Text(text = index.toString(), color = Color.White)
                    } else {
                        Text(text = index.toString(), color = Color.Red)
                    }
                }
            }
        }

        LaunchedEffect(pagerState) {
            snapshotFlow { pagerState.currentPage }.collect { page ->
                if (page != selectedRow) {
                    //This doesn't work if selectedRow = page happens before the other code due to recomposition
                    //If it's after, it executes but it doesn't look right as it moves then highlights

                    selectedRow = page

                    listState.scrollToItem(0)
                    try {
                        listState.animateScrollBy(distanceToMiddleOfScreen(buttonHeight, listVisibleHeight, page))
                    } catch (exception: Exception) {
                        Log.e("scrollBug", "animateScrollBy Exception", exception)
                    }
                }
            }
        }

        HorizontalPager(
            count = 48,
            state = pagerState,
            modifier = Modifier
                .fillMaxWidth()
                .fillMaxHeight()
                .background(Color.White),
        ) { page ->
            Text(text = page.toString())
        }
    }
}

private fun distanceToMiddleOfScreen(itemHeight: Int, totalListHeight: Int, offset: Int): Float {
    return itemHeight.toFloat() * offset - (totalListHeight / 2) + itemHeight
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-04-05 07:00:35

您的寻呼机的行为很奇怪,因为您在reach重组时创建了它的状态:

代码语言:javascript
运行
复制
val pagerState = PagerState(currentPage = selectedRow)

这个初始化器使您可以在您自己的状态中使用,您负责在重新组合之间记住这一点。

在视图中使用它时,若要在重新组合之间保存其状态,需要使用“记住版本”:

代码语言:javascript
运行
复制
val pagerState = rememberPagerState()

在此之后,您的LaunchedEffect将不会重新启动,也不会停止您的animateScrollBy

在关闭这个特征请求之前,我想不出滚动问题的通用解决方案。但是,如果所有项都大小相等,则可以计算当前滚动位置、最终滚动位置,因此可以计算要滚动的差值:

代码语言:javascript
运行
复制
LaunchedEffect(Unit) {
    snapshotFlow { pagerState.currentPage }.collect { page ->
        if (page != selectedRow) {
            selectedRow = page

            val currentOffset = listState.firstVisibleItemIndex * buttonHeight + listState.firstVisibleItemScrollOffset
            val finalOffset = distanceToMiddleOfScreen(buttonHeight, listVisibleHeight, page)
            listState.animateScrollBy(finalOffset - currentOffset)
        }
    }
}

另外,您的distanceToMiddleOfScreen也不准确,可以这样修正:

代码语言:javascript
运行
复制
return itemHeight * (offset + 0.5f) - totalListHeight / 2

结果:

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71743490

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档