2

我有一个 MaterialApp,其中有一个 IndexedStack 作为其主页,用于 BottomBarNavigation。现在,在“选项卡”之一中,我希望像在 iOS 中那样完成页面转换。

部分技巧可以使用 Navigator.push 中的 CupertinoPageRoute 完成,如下所示:

Navigator.of(context, rootNavigator: true).push(CupertinoPageRoute<bool>(
      //fullscreenDialog: true,
      builder: (BuildContext context) => new DescriptionPage(),

    ));

这导致新页面作为 iOS 应用程序从右侧滑动。但是,正如 CupertinoPageRoute 的文档中所说,我还希望将第一页向右移动视差:

当另一页进入以覆盖它时,该页也会以视差向左移动。

如果第一页本身是通过“Navigator.push(CupertinoPageRoute ...”创建的,这将完成,但正如我所提到的,我的第一页是应用程序主页的主要页面之一。

当前过渡样式: 新页面从右滑入,但当前页面不向左移动

如您所见,当前页面不会向左移动。可能有一种方法可以使当前页面的小部件充当由 CupertinoPageRoute 构建的小部件,以便当前页面本身在新页面进入时向左滑动。

4

2 回答 2

4

theme:MaterialApp 的参数中,试试这个:

MaterialApp(
  theme: ThemeData( //or replace with your custom ThemeData.copywith()
    pageTransitionsTheme: PageTransitionsTheme(
      builders: {
        TargetPlatform.android: CupertinoPageTransitionsBuilder(),
        TargetPlatform.iOS: CupertinoPageTransitionsBuilder()
      }
    ),
  ),
)
于 2020-04-21T17:54:43.107 回答
1

如果您运行下面的代码,您将看到第一个选项卡正在执行您所看到的操作,而第二个选项卡是您所期望的。

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: CupertinoStoreHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class CupertinoStoreHomePage extends StatelessWidget {
  const CupertinoStoreHomePage({title});

  @override
  Widget build(BuildContext context) {
    return CupertinoTabScaffold(
      tabBar: CupertinoTabBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(CupertinoIcons.bell),
            title: Text('TAB1'),
          ),
          BottomNavigationBarItem(
            icon: Icon(CupertinoIcons.bell_solid),
            title: Text('TAB2'),
          ),
        ],
      ),
      tabBuilder: (context, index) {
        switch (index) {
          case 0:
            return CupertinoTabView(builder: (context) {
              return CupertinoPageScaffold(
                child: TAB1(),
              );
            });
          case 1:
            return CupertinoTabView(
              builder: (context) {
                return CupertinoPageScaffold(
                  child: TAB2(),
                );
              },
              routes: {
                '/screen': (ctx) => NextScreen(),
              },
            );

          default:
            return Container();
        }
      },
    );
  }
}

class TAB1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("TAB1"),
      ),
      body: Container(
        child: FlatButton(
          child: Text("Go To Next Screen"),
          onPressed: () => Navigator.of(context)
              .push(MaterialPageRoute(builder: (_) => NextScreen())),
        ),
      ),
    );
  }
}

class TAB2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("TAB2"),
      ),
      body: Container(
          child: FlatButton(
        child: Text("Go To Next Screen"),
        onPressed: () => Navigator.of(context).pushNamed("/screen"),
      )),
    );
  }
}

class NextScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
      child: Scaffold(
        appBar: AppBar(
          title: Text("NextScreen"),
        ),
        body: Container(
          child: Text("NextScreen"),
        ),
      ),
    );
  }
}

使用 Navigator.of(ctx).push 时,应用程序尝试在根导航器上推送新屏幕,在您的情况下是标签栏,但它无法替换标签栏,因此您会看到不完整的动画。但是,在第二种方法中,您在相关选项卡中定义了路由并使用 Push Named,应用程序使用分配给该选项卡的导航器,从而获得预期的结果。

快乐编码!

于 2020-04-21T20:51:41.220 回答