Flutter Tab 导航使用 auto_route,如何避免 SliverAppBar 上的转换

问题描述 投票:0回答:1

所以我正在启动一个项目,其中主页(

HomeScreen
)有一个
NavigationBar
和几个子屏幕。为了本演示的目的,我创建了两个子屏幕,名为
StarScreen
SquareScreen
Auto_Route是我的路由器。

这就是我想到的:

@RoutePage()
class HomeScreen extends StatelessWidget {
  const HomeScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return AutoTabsRouter(
      routes: [
        StarRoute(),
        SquareRoute(),
      ],
      transitionBuilder: (context, child, animation) => FadeTransition(
        opacity: animation,
        child: child,
      ),
      builder: (BuildContext context, Widget child) {
        final tabsRouter = AutoTabsRouter.of(context);

        return Scaffold(
          body: child,
          bottomNavigationBar: NavigationBar(
            selectedIndex: tabsRouter.activeIndex,
            onDestinationSelected: (index) {
              tabsRouter.setActiveIndex(index);
            },
            destinations: GenerateDestinations(),
          ),
        );
      },
    );
  }
}

效果很好,过渡时子屏幕会闪烁,但导航栏上没有过渡。正是我想要的。

现在,我想用 AppBar 来升级它。我可以简单地在我的脚手架中添加一个

appBar: AppBar()
就这样了。但它不起作用,因为我想在我的页面上使用 SliverAppBar 和 SliverList,所以我需要将所有内容放在
CustomScrollView
中。我的方法是将
CustomScrollView
整合到
HomeScreen
的主体中,并在
StarScreen
SquareScreen
中定义其他Sliver。所以我的
HomeScreen
看起来像这样:

@RoutePage()
class HomeScreen extends StatelessWidget {
  const HomeScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return AutoTabsRouter(
      routes: [
        StarRoute(),
        SquareRoute(),
      ],
      transitionBuilder: (context, child, animation) => FadeTransition(
        opacity: animation,
        child: child,
      ),
      builder: (BuildContext context, Widget child) {
        final tabsRouter = AutoTabsRouter.of(context);

        return Scaffold(
          body: SafeArea(
            child: CustomScrollView(
              slivers: [
                SliverAppBar(
                  floating: true,
                  snap: true,
                  title: Text(
                    'Title',
                    style: TextStyle(
                      color: Theme.of(context).colorScheme.onPrimaryContainer,
                    ),
                  ),
                  backgroundColor:
                      Theme.of(context).colorScheme.primaryContainer,
                ),
                child, // Only this child should be refreshed when changing page
              ],
            ),
          ),
          bottomNavigationBar: NavigationBar(
            selectedIndex: tabsRouter.activeIndex,
            onDestinationSelected: (index) {
              tabsRouter.setActiveIndex(index);
            },
            destinations: GenerateDestinations(),
          ),
        );
      },
    );
  }
}

我的其他屏幕看起来像这样:

@RoutePage()
class StarScreen extends StatelessWidget {
  const StarScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return SliverList(
      delegate: SliverChildListDelegate(
        [
          Container(
            // ...
          ),
          // ...
        ],
      ),
    );
  }
}

问题是,当我执行此操作时,我收到如下错误:

A RenderViewport expected a child of type RenderSliver but received a child of type RenderErrorBox.

所以,我知道 Slivers 的渲染方式与 box-widgets 不同(如果这是正确的术语)。我认为这就是它不起作用的原因。但是,如果我将 SliverList 直接放在

child
CustomScrollView
的位置(而不是从另一个文件导入),它就可以工作。

我应该以不同的方式声明我的

StarScreen
无状态小部件吗?

总体来说我的方法正确吗?

flutter flutter-sliver
1个回答
0
投票

我知道它可能已经晚了,但使用

AutoTabsRouter.builder
为我修复了它。

© www.soinside.com 2019 - 2024. All rights reserved.