【问题标题】:SliverAppBar with TabBarSliverAppBar 和 TabBar
【发布时间】:2018-10-30 05:27:01
【问题描述】:

如何在 Flutter 中将 TabBar 添加到 SliverAppBar?到目前为止,当我将 bottom 添加到 SliverAppBar 时,title 被固定到这些选项卡上,而我希望它位于这些选项卡上方。
有什么想法吗?

我的代码:

class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin{
  TabController controller;


  @override
  void initState() {
    super.initState();
    controller = new TabController(length: 3, vsync: this);
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new CustomScrollView(
        slivers: <Widget>[
          new SliverAppBar(
            pinned: true,
            flexibleSpace: new FlexibleSpaceBar(
              title: new Text("Some title"),
            ),
            expandedHeight: 160.0,
            bottom: new TabBar(tabs: [
              new Tab(text: 'Tab 1'),
              new Tab(text: 'Tab 2'),
              new Tab(text: 'Tab 3'),
            ],
            controller: controller,
            ),
          ),
          new SliverList(
            delegate: new SliverChildBuilderDelegate(
              (context, idx) {
                return new ListTile(
                  title: new Text("$idx"),
                );
              },
              childCount: 20,
            ),
          ),
        ],
      ),
    );
  }
}

【问题讨论】:

标签: flutter


【解决方案1】:

几周前我遇到了同样的问题,我可以使用 SliverAppBarFlexibleSpaceBarSliverPersistentHeader 来解决。

检查我的代码

  @override
    Widget build(BuildContext context) {
      return Scaffold(
        body: DefaultTabController(
          length: 2,
          child: NestedScrollView(
            headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
              return <Widget>[
                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,
                      )),
                ),
                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"),
            ),
          ),
        ),
      );
    }

这是 SliverPersistentHeader 的实现

  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;
    }
  }

如果你想检查,我写了一篇关于它的帖子:

https://medium.com/@diegoveloper/flutter-collapsing-toolbar-sliver-app-bar-14b858e87abe

【讨论】:

  • 尊重!谢谢!
  • 当我们在选项卡中有列表视图时布局崩溃。请帮忙
  • 在这个实现中tabbar在header之后,如何让透明背景的tabbar“over”底部AppBar图片?
  • tabview 在 tabbar 后面。如何让它伸展?
  • @diegoveloper tabbarview在tabbar后面重叠,你知道怎么解决吗?谢谢
【解决方案2】:

FlexibleSpaceBar 堆叠在工具栏和标签栏的后面。 https://docs.flutter.io/flutter/material/SliverAppBar/flexibleSpace.html

你应该把你的标题放在 SilverAppBar:title 中,而不是放在 flexibleSpace 中。

在你的代码中替换

flexibleSpace: new FlexibleSpaceBar(
                      title: new Text("Some title"),
               ),

title: new Text("Some title"),

【讨论】:

  • 如果你把它放在SilverAppBar:title中,那么标题就不会展开了
【解决方案3】:

您可以使用 titlePadding 进行填充:

              SliverAppBar(
                  pinned: true,
                  expandedHeight: 250,
                  primary: true,
                  forceElevated: true,
                  flexibleSpace: FlexibleSpaceBar(
                    titlePadding: EdgeInsets.only(bottom: 62),
                    title: Text(data.name),
                    centerTitle: true,
                    background: data.logo != null
                        ? Padding(
                            padding: const EdgeInsets.only(bottom: 46),
                            child: Container(
                              color: Colors.black,
                            ),
                          )
                        : null,
                  ),
                  bottom: TabBar(
                    tabs: [
                      Tab(text: "Tab1"),
                      Tab(text: "Tab2"),
                      Tab(text: "Tab3"),
                      Tab(text: "Tab4"),
                    ],
                  ),
                ),

【讨论】:

    【解决方案4】:
    class Menu extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return DefaultTabController(
          length: 2,
          child: SafeArea(
            child: Scaffold(
              body: Consumer<MenuBlock>(
                  builder: (context, appController, child) {
                return CustomScrollView(
                  slivers: <Widget>[
                    SliverAppBar(
                      floating: true,
                      pinned: false,
                      snap: true,
                      forceElevated: true,
                      elevation: 1,
                      expandedHeight: 50.0,
                      title: Text('TITLE'),
                      actions: <Widget>[
                        IconButton(
                          icon: const Icon(Icons.add_circle),
                          tooltip: 'Add new entry',
                          onPressed: () {/* ... */},
                        ),
                      ],
                      bottom: TabBar(
                        tabs: [
                          Tab(text: "TAB1"),
                          Tab(text: "TAB2"),
                        ],
                      ),
                    ),
                    SliverList(
                      delegate: SliverChildListDelegate(
                        <Widget>[
                          Container(
                            // or SizedBox, etc.
                            height: 4200,
                            child: TabBarView(
                              children: [
                         
                            ),
                          ),
                        ],
                      ),
                    ),
                  ],
                );
              }),
            ),
          ),
        );
      }
    }
    

    【讨论】:

    • 虽然这可能会回答问题,但您应该edit 您的回答包括对如何此代码块回答问题的解释。这有助于提供上下文,并使您的答案对以后可能遇到相同问题的其他人更有用。
    猜你喜欢
    • 2021-05-14
    • 2020-04-17
    • 1970-01-01
    • 2018-11-17
    • 2019-08-06
    • 2021-01-14
    • 2022-12-18
    • 2018-12-19
    • 1970-01-01
    相关资源
    最近更新 更多