gpt4 book ai didi

flutter - 使用 ScrollNotification 滚动出 SliverList 子项时获取该子项的索引

转载 作者:行者123 更新时间:2023-12-03 18:48:47 24 4
gpt4 key购买 nike

我有一个包含 sliverlist 和 sliverAppbar 的应用程序。我需要获取sliverlist中每个项目的当前滚动位置onscroll并确定它是否已经越过 sliverAppbar 并使用项目的标题更新 sliverappbar。假设从 Item1 穿过 SliverAppBar 开始,这意味着我正在查看 Item1 内容,当 Item2 穿过 SliverAppBar 时,将 SliverAppBar 更新为标题 Item2表示用户正在查看 Item2内容
我正在尝试使用 NotificationListener<ScrollEndNotification> 来实现这一点但我被困在第二个 NotificationListener 应该向父级顶部发出通知
在此行 ScrollEndNotification(metrics: , context:context).dispatch(context);它抛出一个错误,我应该提供一个 metrics我不知道要提供什么的参数。

            SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
ScrollEndNotification(metrics: , context:context).dispatch(context);
return AutoScrollTag(
key: ValueKey(index),
controller: controller,
index: index,
child: Padding(
padding: const EdgeInsets.only(
top: 30.0, left: 20.0, right: 20.0),
child: Container(
color: Colors.red,
//height: 120.0
//height: A varying height

),),},); ),
完整的代码是
           Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[100],
body: NotificationListener<ScrollEndNotification>(
onNotification: (notification) {
if (notification is ScrollEndNotification) {
///Here I need to know what widget index bubbled the notification, its position
///on the screen and its index
//in the list, in order to do further implementation like update the
//SliverAppBar
print('$notification');
return true;
},
child: CustomScrollView(
controller: controller
slivers: <Widget>[
SliverAppBar(
title: Text(title),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
ScrollEndNotification(metrics: , context:context).dispatch(context);
return AutoScrollTag(
key: ValueKey(index),
controller: controller,
index: index,
child: Padding(
padding: const EdgeInsets.only(
top: 30.0, left: 20.0, right: 20.0),
child: Container(
color: Colors.red,
//height: 120.0
//height: A varying height
),),},); ),
另外,如果您对我如何实现这一点有更好的实现,请帮助我。简而言之,我需要跟踪项目何时从屏幕上滚动并得到说 index它在 Sliverlist 中。请记住, item有一个可变大小的容器,可根据其中的子项数量进行扩展。这是电子商务应用程序中常见的 UX 模式。例如,当用户向下滚动时查看菜单并在标题穿过屏幕时更新用户正在查看的菜单。
提供 link到要点,以便您了解完整的实现

最佳答案

您不需要使用 ScrollEndNotification .事实上,当 SliverAppBar 时,我发现 UX 的响应速度更快。滚动期间更新,这是与 onscroll 最相似的结果无论如何处理程序。如果您更改为仅使用常规 ScrollNotification,您使用通知的想法很有效。 .在这种情况下,问题实际上非常简单,因为 SliverList children 有固定 高度。 child 总是 150 像素高(120 像素是内容与 30 填充)。
考虑到这一点,我们实际上可以计算在通知处理程序中滚动出的子项的索引。我不得不改变 SliverAppBar成为 pinned在滚动期间保持栏(和滚动出的索引)可见。
请注意,如果子项的高度不固定,我们每次都需要计算每一行的高度,因此需要重构这种方法。
本质上的逻辑是:

// Get scroll position `progress` and subtract `SliverAppBar` height.
double progress = notification.metrics.pixels - 60;
// Calculate index scrolled off the screen.
index = (progress ~/ 150) - 1;
我还添加了一个有效的索引检查,以便不会错误地显示负索引。
((index >= 0) ? index.toString() : "")
完整代码:
class _MyHomePageState extends State<MyHomePage> {
late AutoScrollController controller =
AutoScrollController(initialScrollOffset: 0);
int index = 0;

@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[100],
body: NotificationListener<ScrollNotification>(
onNotification: (ScrollNotification notification) {
double progress = notification.metrics.pixels - 60;
setState(() {
index = (progress ~/ 150) - 1;
});
return true;
},
child: CustomScrollView(
controller: controller,
slivers: <Widget>[
SliverAppBar(
title: Text(
widget.title + " " + ((index >= 0) ? index.toString() : "")),
expandedHeight: 60,
pinned: true,
),
SliverList(delegate: SliverChildBuilderDelegate(
(BuildContext context, int localIndex) {
return AutoScrollTag(
key: ValueKey(localIndex),
controller: controller,
index: localIndex,
child: Padding(
padding: const EdgeInsets.only(
top: 30.0, left: 20.0, right: 20.0),
child: Container(color: Colors.red, height: 120.0),
),
);
},
)),
],
),
),
);
}
}

关于flutter - 使用 ScrollNotification 滚动出 SliverList 子项时获取该子项的索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67289817/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com