首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用tabBar实现sliverAppBar

如何使用tabBar实现sliverAppBar
EN

Stack Overflow用户
提问于 2018-06-07 20:53:02
回答 4查看 23.3K关注 0票数 19

flutter文档显示了一个demo对于SliverAppBar+TabBar+TabBarView with ListView使用NestedScrollView,而且它有点复杂,所以我想知道有没有一种简单而明确的方法来实现它。我试过这个:

代码语言:javascript
运行
复制
CustomScrollView
  slivers:
    SliverAPPBar
      bottom: TabBar
    TabBarView
      children: MyWidget(list or plain widget)

获取错误:

flutter:以下断言被抛出构建可滚动(axisDirection:对,物理:

RenderSliver : RenderViewport需要类型为flutter的子项,但收到的子项类型为_RenderExcludableScrollSemantics。

flutter: RenderObjects期望特定类型的子项,因为它们在布局和绘制期间与子项进行协调。例如,RenderSliver不能是RenderBox的子级,因为RenderSliver不理解RenderBox布局协议。

flutter:抛出了另一个异常:'package:flutter/src/widgets/framework.dart':断言失败:第3497行pos 14:'owner。_debugCurrentBuildTarget == this':不是真的。

下面是我的代码:

代码语言:javascript
运行
复制
import 'package:flutter/material.dart';

main(List args) {
  runApp(MyScrollTabListApp());
}

class MyScrollTabListApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(title: "aa", home: MyScrollTabListHomePage());
  }
}

class MyScrollTabListHomePage extends StatefulWidget {
  @override
  MyScrollTabListHomePageState createState() {
    return new MyScrollTabListHomePageState();
  }
}

class MyScrollTabListHomePageState extends State
    with SingleTickerProviderStateMixin {
  final int _listItemCount = 300;
  final int _tabCount = 8;
  TabController _tabController;

  @override
  void initState() {
    _tabController = TabController(length: _tabCount, vsync: this);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        slivers: [
          SliverAppBar(
            expandedHeight: 240.0,
            title: Text("Title"),
            pinned: true,
            bottom: TabBar(
              controller: _tabController,
              isScrollable: true,
              tabs: List.generate(_tabCount, (int i) {
                return Tab(text: "TAB$i");
              }),
            ),
          ),
          TabBarView(
            controller: _tabController,
            children: List.generate(_tabCount, (int i) {
              return Text('line $i');
            }),
          ),
        ],
      ),
    );
  }
}

对于官方演示,它使用的struct如下所示

代码语言:javascript
运行
复制
DefaultTabController
    NestedScrollView
      headerSliverBuilder
        SliverOverlapAbsorber
          handle
          SliverAppBar
        TabBarView
          CustomScrollView
            SliverOverlapInjector
              handle
              SliverPadding
EN

回答 4

Stack Overflow用户

发布于 2019-05-30 02:29:17

使用NestedScrollView,这里是工作代码。

代码语言:javascript
运行
复制
@override
Widget build(BuildContext context) {
  return Scaffold(
    body: DefaultTabController(
      length: 2,
      child: NestedScrollView(
        headerSliverBuilder: (context, value) {
          return [
            SliverAppBar(
              bottom: TabBar(
                tabs: [
                  Tab(icon: Icon(Icons.call), text: "Call"),
                  Tab(icon: Icon(Icons.message), text: "Message"),
                ],
              ),
            ),
          ];
        },
        body: TabBarView(
          children: [
            CallPage(),
            MessagePage(),
          ],
        ),
      ),
    ),
  );
}
票数 20
EN

Stack Overflow用户

发布于 2018-06-14 20:53:38

下面是一个使用SilverAppBar的TabView示例

代码语言:javascript
运行
复制
class SilverAppBarWithTabBarScreen extends StatefulWidget {
  @override
  _SilverAppBarWithTabBarState createState() => _SilverAppBarWithTabBarState();
}

class _SilverAppBarWithTabBarState extends State
    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: [
          new SliverAppBar(
            title: Text("Silver AppBar With ToolBar"),
            pinned: true,
            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(
          new SliverFillRemaining(
        child: TabBarView(
          controller: controller,
          children: [
               Text("Tab 1"),
               Text("Tab 2"),
               Text("Tab 3"),
             ],
            ),
          ),
        ],
      ),
    );
  }
}
票数 6
EN

Stack Overflow用户

发布于 2021-02-26 00:08:12

是啊。您可以使用NestedScrollView来实现Tabs。下面是一些附加代码。

代码语言:javascript
运行
复制
class AppView extends StatelessWidget {
final double _minValue = 8.0;

@override
Widget build(BuildContext context) {
final textTheme = Theme.of(context).textTheme;

return Scaffold(
  appBar: MyAppBar(),
  drawer: DrawerDialog(),
  body: DefaultTabController(
    length: 3,
    child: SafeArea(
      child: NestedScrollView(
        body: TabBarView(
          children: [Text("Page 1"), Text("Page 2"), Text("Page 3")],
        ),
        headerSliverBuilder:
            (BuildContext context, bool innerBoxIsScrolled) => [
          SliverPadding(
            padding: EdgeInsets.all(_minValue * 2.5),
            sliver: SliverToBoxAdapter(
              child: Text(
                "Hiding Header",
                style: textTheme.headline6,
                textAlign: TextAlign.center,
              ),
            ),
          ),
          SliverAppBar(
            backgroundColor: Colors.grey[100],
            pinned: true,
            elevation: 12.0,
            leading: Container(),
            titleSpacing: 0.0,
            toolbarHeight: 10,
            bottom: TabBar(tabs: [
              Tab(
                child: Text(
                  "All",
                  style: textTheme.subtitle2,
                ),
              ),
              Tab(
                child: Text(
                  "Categories",
                  style: textTheme.subtitle2,
                ),
              ),
              Tab(
                child: Text(
                  "Upcoming",
                  style: textTheme.subtitle2,
                ),
              ),
            ]),
          ),
        ],
      ),
    ),
  ),
);

}}

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50741732

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档