滚动到Jetpack Compose中嵌套元素的绝对坐标位置。

huangapple go评论61阅读模式
英文:

Scroll to absolute coordinates of nested element in Jetpack Compose

问题

这是我使用的一个组合项。它嵌套在不同深度的不同组合项中。

@Composable
fun ScrollTest(
    text: String,
    scrollState: ScrollState?,
) {
    if (text.isNotEmpty()) {
        var yCoordinates by remember { mutableStateOf(0) }
        LaunchedEffect(text, block = {
            launch {
                scrollState?.animateScrollTo(yCoordinates)
            }
        })
        Text(
            modifier = Modifier
                .padding(horizontal = 4.dp, vertical = 2.dp)
                .onGloballyPositioned { coordinates ->
                    yCoordinates = coordinates.positionInRoot().y.toInt() - SCROLL_DELTA
                },
            text = text,
        )
    }
}
英文:

https://stackoverflow.com/questions/68406508/jetpack-compose-animatescrollto-to-absolute-coordinates-or-direct-to-element

Here is almost the same question, but I have nested composable in my case, so the accepted answer won't work for it, and when you want to scroll from the bottom of the screen.

relocationRequester didn't help in my case.

I've tried to get the parentCoordinates from coordinates and it doesn't look like a working way.

Here are positions from logs when I scroll a screen, the goal composable somewhere in the middle of the screen.

root > 3804 > parent > 231 > window > 3870
root > 3767 > parent > 231 > window > 3833
root > 3749 > parent > 231 > window > 3815
root > 3725 > parent > 231 > window > 3791
root > 3710 > parent > 231 > window > 3776
root > 3701 > parent > 231 > window > 3767
root > 3692 > parent > 231 > window > 3758
root > 3686 > parent > 231 > window > 3752
root > 3684 > parent > 231 > window > 3750
root > 3682 > parent > 231 > window > 3748
root > 3677 > parent > 231 > window > 3743
root > 3670 > parent > 231 > window > 3736
root > 3661 > parent > 231 > window > 3727
root > 3652 > parent > 231 > window > 3718
root > 3641 > parent > 231 > window > 3707
root > 3631 > parent > 231 > window > 3697
root > 3621 > parent > 231 > window > 3687
root > 3610 > parent > 231 > window > 3676
root > 3599 > parent > 231 > window > 3665
root > 3581 > parent > 231 > window > 3647
root > 3561 > parent > 231 > window > 3627
root > 3539 > parent > 231 > window > 3605
root > 3520 > parent > 231 > window > 3586
root > 3499 > parent > 231 > window > 3565
root > 3479 > parent > 231 > window > 3545
root > 3460 > parent > 231 > window > 3526
root > 3443 > parent > 231 > window > 3509
root > 3430 > parent > 231 > window > 3496
root > 3421 > parent > 231 > window > 3487
root > 3412 > parent > 231 > window > 3478
root > 3396 > parent > 231 > window > 3462
root > 3394 > parent > 231 > window > 3460
root > 3390 > parent > 231 > window > 3456
root > 3381 > parent > 231 > window > 3447
root > 3372 > parent > 231 > window > 3438
root > 3359 > parent > 231 > window > 3425
root > 3343 > parent > 231 > window > 3409
root > 3321 > parent > 231 > window > 3387
root > 3302 > parent > 231 > window > 3368
root > 3284 > parent > 231 > window > 3350
root > 3263 > parent > 231 > window > 3329
root > 3247 > parent > 231 > window > 3313
root > 3232 > parent > 231 > window > 3298
root > 3224 > parent > 231 > window > 3290
root > 3213 > parent > 231 > window > 3279
root > 3200 > parent > 231 > window > 3266
root > 3197 > parent > 231 > window > 3263
root > 3188 > parent > 231 > window > 3254
root > 3179 > parent > 231 > window > 3245
root > 3167 > parent > 231 > window > 3233
root > 3158 > parent > 231 > window > 3224
root > 3147 > parent > 231 > window > 3213
root > 3136 > parent > 231 > window > 3202
root > 3127 > parent > 231 > window > 3193
root > 3114 > parent > 231 > window > 3180
root > 3105 > parent > 231 > window > 3171
root > 3093 > parent > 231 > window > 3159
root > 3083 > parent > 231 > window > 3149
root > 3070 > parent > 231 > window > 3136
root > 3059 > parent > 231 > window > 3125
root > 3045 > parent > 231 > window > 3111
root > 3032 > parent > 231 > window > 3098
root > 3018 > parent > 231 > window > 3084
root > 3004 > parent > 231 > window > 3070
root > 2991 > parent > 231 > window > 3057
root > 2975 > parent > 231 > window > 3041
root > 2962 > parent > 231 > window > 3028
root > 2947 > parent > 231 > window > 3013
root > 2932 > parent > 231 > window > 2998
root > 2918 > parent > 231 > window > 2984
root > 2908 > parent > 231 > window > 2974
root > 2894 > parent > 231 > window > 2960
root > 2882 > parent > 231 > window > 2948
root > 2869 > parent > 231 > window > 2935
root > 2857 > parent > 231 > window > 2923
root > 2841 > parent > 231 > window > 2907
root > 2826 > parent > 231 > window > 2892
root > 2813 > parent > 231 > window > 2879
root > 2796 > parent > 231 > window > 2862
root > 2778 > parent > 231 > window > 2844
root > 2761 > parent > 231 > window > 2827
root > 2739 > parent > 231 > window > 2805
root > 2716 > parent > 231 > window > 2782
root > 2692 > parent > 231 > window > 2758
root > 2671 > parent > 231 > window > 2737
root > 2650 > parent > 231 > window > 2716
root > 2631 > parent > 231 > window > 2697
root > 2611 > parent > 231 > window > 2677
root > 2598 > parent > 231 > window > 2664
root > 2581 > parent > 231 > window > 2647
root > 2563 > parent > 231 > window > 2629
root > 2545 > parent > 231 > window > 2611
root > 2530 > parent > 231 > window > 2596
root > 2520 > parent > 231 > window > 2586
root > 2510 > parent > 231 > window > 2576
root > 2504 > parent > 231 > window > 2570
root > 2503 > parent > 231 > window > 2569
root > 2501 > parent > 231 > window > 2567
root > 2488 > parent > 231 > window > 2554
root > 2432 > parent > 231 > window > 2498
root > 2374 > parent > 231 > window > 2440
root > 2266 > parent > 231 > window > 2332
root > 2205 > parent > 231 > window > 2271
root > 2161 > parent > 231 > window > 2227
root > 2113 > parent > 231 > window > 2179
root > 2068 > parent > 231 > window > 2134
root > 2024 > parent > 231 > window > 2090
root > 2003 > parent > 231 > window > 2069
root > 1988 > parent > 231 > window > 2054
root > 1962 > parent > 231 > window > 2028
root > 1936 > parent > 231 > window > 2002
root > 1907 > parent > 231 > window > 1973
root > 1897 > parent > 231 > window > 1963
root > 1864 > parent > 231 > window > 1930
root > 1844 > parent > 231 > window > 1910
root > 1817 > parent > 231 > window > 1883
root > 1790 > parent > 231 > window > 1856
root > 1759 > parent > 231 > window > 1825
root > 1739 > parent > 231 > window > 1805
root > 1700 > parent > 231 > window > 1766
root > 1670 > parent > 231 > window > 1736
root > 1639 > parent > 231 > window > 1705
root > 1608 > parent > 231 > window > 1674
root > 1583 > parent > 231 > window > 1649
root > 1559 > parent > 231 > window > 1625
root > 1537 > parent > 231 > window > 1603
root > 1516 > parent > 231 > window > 1582
root > 1487 > parent > 231 > window > 1553
root > 1468 > parent > 231 > window > 1534
root > 1446 > parent > 231 > window > 1512
root > 1427 > parent > 231 > window > 1493
root > 1414 > parent > 231 > window > 1480
root > 1391 > parent > 231 > window > 1457
root > 1374 > parent > 231 > window > 1440
root > 1349 > parent > 231 > window > 1415
root > 1324 > parent > 231 > window > 1390
root > 1302 > parent > 231 > window > 1368
root > 1277 > parent > 231 > window > 1343
root > 1246 > parent > 231 > window > 1312
root > 1224 > parent > 231 > window > 1290
root > 1199 > parent > 231 > window > 1265
root > 1176 > parent > 231 > window > 1242
root > 1149 > parent > 231 > window > 1215
root > 1127 > parent > 231 > window > 1193
root > 1105 > parent > 231 > window > 1171
root > 1089 > parent > 231 > window > 1155
root > 1075 > parent > 231 > window > 1141
root > 1063 > parent > 231 > window > 1129
root > 1045 > parent > 231 > window > 1111
root > 1031 > parent > 231 > window > 1097
root > 1021 > parent > 231 > window > 1087
root > 1020 > parent > 231 > window > 1086
root > 1010 > parent > 231 > window > 1076
root > 1001 > parent > 231 > window > 1067
root > 994 > parent > 231 > window > 1060
root > 989 > parent > 231 > window > 1055
root > 985 > parent > 231 > window > 1051
root > 982 > parent > 231 > window > 1048
root > 980 > parent > 231 > window > 1046
root > 979 > parent > 231 > window > 1045
root > 978 > parent > 231 > window > 1044
root > 977 > parent > 231 > window > 1043
root > 962 > parent > 231 > window > 1028
root > 933 > parent > 231 > window > 999
root > 902 > parent > 231 > window > 968
root > 871 > parent > 231 > window > 937
root > 817 > parent > 231 > window > 883
root > 778 > parent > 231 > window > 844
root > 744 > parent > 231 > window > 810
root > 705 > parent > 231 > window > 771
root > 657 > parent > 231 > window > 723
root > 628 > parent > 231 > window > 694
root > 593 > parent > 231 > window > 659
root > 559 > parent > 231 > window > 625
root > 524 > parent > 231 > window > 590
root > 485 > parent > 231 > window > 551
root > 449 > parent > 231 > window > 515
root > 414 > parent > 231 > window > 480
root > 383 > parent > 231 > window > 449
root > 348 > parent > 231 > window > 414
root > 320 > parent > 231 > window > 386
root > 294 > parent > 231 > window > 360
root > 263 > parent > 231 > window > 329
root > 232 > parent > 231 > window > 298
root > 221 > parent > 231 > window > 287

Here is a composable that I use. It's nested to different composables with different nested deep

 @Composable
fun ScrollTest(
text: String,
scrollState: ScrollState?,
) {
if (text.isNotEmpty()) {
var yCoordinates by remember { mutableStateOf(0) }
LaunchedEffect(text, block = {
launch {
scrollState?.animateScrollTo(yCoordinates)
}
})
Text(
modifier = Modifier
.padding(horizontal = 4.dp, vertical = 2.dp)
.onGloballyPositioned { coordinates ->
yCoordinates = coordinates.positionInRoot().y.toInt() - SCROLL_DELTA
},
text = text,
)
}
}

答案1

得分: 1

Ok, I found a way. And it looks simple when I saw it
如果我们无法获得所需的绝对位置,我们需要获取当前位置Y,以及视图的相对Y位置,并找到合适的值

@Composable
fun ScrollTest(
    text: String,
    scrollState: ScrollState?,
) {
    if (text.isNotEmpty()) {
        var scrollTo by remember { mutableStateOf(0) }
        LaunchedEffect(text, block = {
            launch {
                scrollState?.animateScrollTo(scrollTo)
            }
        })
        Text(
            modifier = Modifier
                .onGloballyPositioned { coordinates ->
                    val currentYPosition = scrollState?.value ?: 0
                    val yCoordinate = coordinates.positionInRoot().y
                    scrollTo = (currentYPosition + yCoordinate - SCROLL_DELTA).toInt()
                },
            text = text
        )
    }
}

(Note: The code is provided in both Chinese and English, as per your request.)

英文:

Ok, I found a way. And it looks simple when I saw it
If we can't get the absolute position we need to get the current position Y, and that relative y of view. and find the propper value

@Composable
fun ScrollTest(
text: String,
scrollState: ScrollState?,
) {
if (text.isNotEmpty()) {
var scrollTo by remember { mutableStateOf(0) }
LaunchedEffect(text, block = {
launch {
scrollState?.animateScrollTo(scrollTo)
}
})
Text(
modifier = Modifier
.onGloballyPositioned { coordinates ->
val currentYPosition = scrollState?.value ?: 0
val yCoordinate = coordinates.positionInRoot().y
scrollTo = (currentYPosition + yCoordinate - SCROLL_DELTA).toInt()
},
text = text
)
}
}

huangapple
  • 本文由 发表于 2023年5月24日 22:04:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/76324408.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定