【问题标题】:Prevent content from scrolling beneath SliverAppBar防止内容在 SliverAppBar 下方滚动
【发布时间】:2020-03-17 02:42:43
【问题描述】:

我有一个 Sliver 布局,顶部有一个 SliverAppBar,向下滚动时会折叠。

问题如下:

我的 Sliver 布局的内容在 SliverAppBar 下滚动:(不需要)

相反,我想在 SliverAppBar 折叠后立即禁止进一步滚动。

这应该是您可以向下滚动的最大状态:

代码:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  var scrollController = ScrollController();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: Home());
  }
}

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: DefaultTabController(
          length: 2,
          child: NestedScrollView(
            headerSliverBuilder:
                (BuildContext context, bool innerBoxIsScrolled) {
              return [
                SliverAppBar(
                  expandedHeight: 200.0,
                  floating: false,
                  pinned: true,
                  flexibleSpace: FlexibleSpaceBar(
                      centerTitle: true,
                      title: Text("Collapsing Toolbar",
                          style: TextStyle(
                            color: Colors.white,
                            fontSize: 16.0,
                          )),
                      background: Image.network(
                        "https://images.pexels.com/photos/396547/pexels-photo-396547.jpeg?auto=compress&cs=tinysrgb&h=350",
                        fit: BoxFit.cover,
                      )),
                ),
                SliverPadding(
                  padding: new EdgeInsets.all(16.0),
                  sliver: new SliverList(
                    delegate: new SliverChildListDelegate([
                      TabBar(
                        labelColor: Colors.black87,
                        unselectedLabelColor: Colors.grey,
                        tabs: [
                          new Tab(icon: new Icon(Icons.info), text: "Tab 1"),
                          new Tab(
                              icon: new Icon(Icons.lightbulb_outline),
                              text: "Tab 2"),
                        ],
                      ),
                    ]),
                  ),
                ),
              ];
            },
            body: Center(
              child: Text("Sample text"),
            ),
          ),
        ));
  }
}

【问题讨论】:

    标签: user-interface flutter flutter-layout flutter-sliver


    【解决方案1】:

    您需要SliverPersistentHeader_SliverAppBarDelegate,请参阅下面的完整代码
    您可以复制粘贴运行完整代码
    详情请参考https://medium.com/@diegoveloper/flutter-collapsing-toolbar-sliver-app-bar-14b858e87abe

    代码sn-p

    SliverPersistentHeader(
                  delegate: _SliverAppBarDelegate(
                    TabBar(
                      labelColor: Colors.black87,
                      unselectedLabelColor: Colors.grey,
                      tabs: [
                        Tab(icon: Icon(Icons.info), text: "Tab 1"),
                        Tab(icon: Icon(Icons.lightbulb_outline), text: "Tab 2"),
                      ],
                    ),
                  ),
                  pinned: true,
                ),
    

    工作演示

    完整代码

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      var scrollController = ScrollController();
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
            title: 'Flutter Demo',
            theme: ThemeData(
              primarySwatch: Colors.blue,
            ),
            home: Home());
      }
    }
    
    class Home extends StatefulWidget {
      @override
      _HomeState createState() => _HomeState();
    }
    
    class _HomeState extends State<Home> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            body: DefaultTabController(
          length: 2,
          child: NestedScrollView(
            headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
              return [
                SliverAppBar(
                  expandedHeight: 200.0,
                  floating: false,
                  pinned: true,
                  snap: false,
                  flexibleSpace: FlexibleSpaceBar(
                      centerTitle: true,
                      title: Text("Collapsing Toolbar",
                          style: TextStyle(
                            color: Colors.white,
                            fontSize: 16.0,
                          )),
                      background: Image.network(
                        "https://images.pexels.com/photos/396547/pexels-photo-396547.jpeg?auto=compress&cs=tinysrgb&h=350",
                        fit: BoxFit.cover,
                      )),
                ),
                SliverPersistentHeader(
                  delegate: _SliverAppBarDelegate(
                    TabBar(
                      labelColor: Colors.black87,
                      unselectedLabelColor: Colors.grey,
                      tabs: [
                        Tab(icon: Icon(Icons.info), text: "Tab 1"),
                        Tab(icon: Icon(Icons.lightbulb_outline), text: "Tab 2"),
                      ],
                    ),
                  ),
                  pinned: true,
                ),
              ];
            },
            body: Center(
              child: Text("Sample text"),
            ),
          ),
        ));
      }
    }
    
    class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
      _SliverAppBarDelegate(this._tabBar);
    
      final TabBar _tabBar;
    
      @override
      double get minExtent => _tabBar.preferredSize.height;
      @override
      double get maxExtent => _tabBar.preferredSize.height;
    
      @override
      Widget build(
          BuildContext context, double shrinkOffset, bool overlapsContent) {
        return new Container(
          child: _tabBar,
        );
      }
    
      @override
      bool shouldRebuild(_SliverAppBarDelegate oldDelegate) {
        return false;
      }
    }
    

    【讨论】:

    • 为什么body会在SliverAppBar之前移动,可以让它们一起移动吗?
    • 如果将Center改为Container,再滚动NestedScrollView,会导致性能异常
    • 经过测试,我的 Android 模拟器在 Container() 下仍然可以正常工作。只有第一次滚动不流畅
    • 这很有帮助,虽然为什么文本(“示例文本”)仍然移动?我怎样才能禁用它
    • 你需要tabbarview
    猜你喜欢
    • 1970-01-01
    • 2021-03-21
    • 2019-11-05
    • 2015-02-18
    • 1970-01-01
    • 2015-09-22
    • 2016-06-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多