flutter 如何使`NestedScrollView`只在需要时滚动其正文

w51jfk4q  于 2023-06-30  发布在  Flutter
关注(0)|答案(2)|浏览(150)

bounty还有4天到期。此问题的答案有资格获得+50声望奖励。GGirotto希望引起更多关注这个问题。

我使用NestedScrollView.headerSliverBuilder属性来重现在滚动屏幕内容时折叠页面标题的相同iOS行为,如下面的GIF所示

到目前为止一切都很顺利。问题是,当屏幕内容低于屏幕边界时,我想阻止NestedScrollView主体滚动,因为理论上没有必要滚动,因为所有内容都是可见的(就像GIF示例一样)。
下面是我在GIF示例中使用的代码:

@override
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
      child: NestedScrollView(
        headerSliverBuilder: (context, innerBoxIsScrolled) => [
          SliverOverlapAbsorber(
            handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
            sliver: SliverSafeArea(
              top: false,
              bottom: false,
              sliver: CupertinoSliverNavigationBar(largeTitle: Text('Page Title')),
            ),
          ),
        ],
        body: Material(
          child: SafeArea(
            top: false,
            child: Center(child: Container(color: Colors.red, height: 50)),
          ),
        ),
      ),
    );
  }
jecbmhm3

jecbmhm31#

使用CustomScrollView代替NestedScrollView

@override
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
      child: CustomScrollView(
        slivers: [
          const SliverSafeArea(
            top: false,
            bottom: false,
            sliver:
                CupertinoSliverNavigationBar(largeTitle: Text('Page Title')),
          ),
          SliverToBoxAdapter(
            child: Material(
              child: SafeArea(
                top: false,
                child: Center(child: Container(color: Colors.red, height: 50)),
              ),
            ),
          ),
        ],
      ),
    );
  }
fcwjkofz

fcwjkofz2#

我建议坚持使用内置的行为来重现这种具有更好的动画,流动性和集成ClampingScroll的减少应用程序栏,您可以使用CustomScrollViewSliverAppBar
您可以随意更改itemCount来查看滚动时的行为,也可以更改FlexibleSpaceBar来重现您想要的AppBar。您可以添加背景图片和更多。

@override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        slivers: <Widget>[
          SliverAppBar(
            pinned: true,
            floating: true,
            snap: true,
            expandedHeight: 200.0,
            flexibleSpace: FlexibleSpaceBar(
              title: Text("Twitter-like AppBar"),
            ),
          ),
          SliverList(
            delegate: SliverChildBuilderDelegate(
              childCount: 3,
              (context, index) => ListTile(
                title: Text('Item #${index}'),
              ),
            ),
          ),
        ],
      ),
    );
  }

相关问题