Flutter 文档非常混乱,SliverOverlapAbsorber 和 SliverOverlapInjector 有什么用?

10 dart flutter

我正在使用flutter 官方文档中的这个例子。这是最小的代码:

List<String> _tabs = ["Tab1", "Tab2"];

@override
Widget build(BuildContext context) {
  return DefaultTabController(
    length: _tabs.length,
    child: Scaffold(
      body: NestedScrollView(
        headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
          return <Widget>[
            // 1/2 remove this widget and only use SliverAppBar
            SliverOverlapAbsorber(
              handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
              child: SliverAppBar(
                title: const Text('Books'),
                pinned: true,
                expandedHeight: 150.0,
                bottom: TabBar(tabs: _tabs.map((name) => Tab(text: name)).toList()),
              ),
            ),
          ];
        },
        body: TabBarView(
          children: _tabs.map((String name) {
            return Builder(
              builder: (BuildContext context) {
                return CustomScrollView(
                  key: PageStorageKey<String>(name),
                  slivers: <Widget>[
                    // 2/2 remove this widget
                    SliverOverlapInjector(handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context)),
                    SliverFixedExtentList(
                      itemExtent: 48.0,
                      delegate: SliverChildBuilderDelegate(
                        (_, i) => ListTile(title: Text('Item $i')),
                        childCount: 30,
                      ),
                    )
                  ],
                );
              },
            );
          }).toList(),
        ),
      ),
    ),
  );
}
Run Code Online (Sandbox Code Playgroud)

问题:

如您所见,如果我在上面的代码中删除了SliverOverlapAbsorberwith SliverOverlapInjector,输出中没有任何变化,拥有它有什么用?文档说

SliverOverlapInjector:此小部件采用 SliverAppBar 的重叠行为,并将其重定向到下面的 SliverOverlapInjector。如果它丢失了,那么即使内部滚动视图认为它没有被滚动,下面的嵌套“内部”滚动视图也可能会在 SliverAppBar 下结束。如果“headerSliv​​erBuilder”仅构建不与下一个条子重叠的小部件,则这不是必需的。

任何人都可以解释它是什么意思以及拥有SliverOverlapInjectorSliverOverlapInjector

小智 6

我用它在NestedScrollView

NestedScrollView(
  headerSliverBuilder: (context, innerBoxIsScrolled) => [
    SliverOverlapAbsorber(
      handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
      sliver: SliverAppBar()
  ],
  body: ...
)
Run Code Online (Sandbox Code Playgroud)

没有它,你体内的一切都会在应用栏下。

查看https://api.flutter.dev/flutter/widgets/NestedScrollView-class.html

据说那里有

SliverOverlapAbsorber(
  // This widget takes the overlapping behavior of the SliverAppBar,
  // and redirects it to the SliverOverlapInjector below. If it is
  // missing, then it is possible for the nested "inner" scroll view
  // below to end up under the SliverAppBar even when the inner
  // scroll view thinks it has not been scrolled.
  // This is not necessary if the "headerSliverBuilder" only builds
  // widgets that do not overlap the next sliver.
  handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
Run Code Online (Sandbox Code Playgroud)