【问题标题】:Flutter navigation for part of screen部分屏幕的颤振导航
【发布时间】:2018-06-22 10:53:41
【问题描述】:

如何将一个小部件推送到另一个小部件的框架中?例如,我有一个带有 2 个容器的列,其中每个容器占据屏幕的一半。我想做一个导航,例如仅在底部容器中。当容器视图拥有自己的 UINavigationController 时,与 iOS 中的逻辑相同。

据我了解,MaterialPageRoute 只能将小部件推送到全屏,并且没有任何其他 Route 类,除了抽象类。也许我应该创建自己的 ModalRoute/TransitionRoute 子类?

【问题讨论】:

  • 您是否需要一些动画,或者为什么您不只是使用条件来替换您的Container 的内容?
  • @creativecreatorormaybenot 我想使用英雄小部件,它的动画由导航器触发。

标签: flutter flutter-layout


【解决方案1】:

您可以使用Navigator 小部件在您的应用中提供任意数量的单独导航器。每个导航器都将维护它自己的导航堆栈。例如,如果你想垂直分割你的应用程序,每一半都有自己的导航堆栈:

Column(
  children: <Widget>[
    Navigator(...),
    Navigator(...)
  ]
)

如果您这样做,您应该考虑如何处理 Android 后退按钮(从技术上讲,您的应用中有 3 个导航器)。默认情况下,它只会监听您的根导航器,因此您必须在小部件层次结构中的某处提供 WillPopScope 小部件,以捕获返回按钮事件并从相应的导航器中弹出。

【讨论】:

  • 你如何精确控制这两个导航器?您如何告诉一个导航推送而另一个导航弹出?如果您想在另一个问题中回答,我可以发布一个问题。提前致谢。
  • 从导航器的子小部件中,Navigator.of(context) 将返回正确的父导航器。
  • @KirollosMorkos 你能举个例子吗?
【解决方案2】:

一种可能的解决方案是在屏幕的该部分创建一个新的 MaterialApp,并像普通应用一样处理那里的所有内容(只是屏幕尺寸不同),如下所示:

Column(
        children: <Widget>[
          Container(
            height: constraints.maxHeight * 0.5,
            width: constraints.maxWidth,
          ),
          Container(
              height: constraints.maxHeight * 0.5,
              width: constraints.maxWidth,
              child: MaterialApp(
                  debugShowCheckedModeBanner: false,
                  theme: ThemeData(
                    primaryColor: Color.fromRGBO(86, 86, 86, 1.00),
                  ),
                  initialRoute: '/W1',
                  routes: {
                    '/W1': (context) => WidgetOne(),
                    '/W2': (context) => WidgetTwo(),
                  })),
        ],
      ),

然后像这样处理小部件的路由:

class WidgetOne extends StatelessWidget {
@override
Widget build(BuildContext context) {
  return GestureDetector(
    onTap: () {
      Navigator.pushNamed(context, '/W2');
    },
    child: Container(color: Colors.green));
    }
  }
}

class WidgetTwo extends StatelessWidget {
@override
Widget build(BuildContext context) {
  return GestureDetector(
    onTap: () {
      Navigator.pushNamed(context, '/W1');
    },
    child: Container(color: Colors.pink));
    }
  }
}

结果: https://i.stack.imgur.com/qyJ5N.gif

【讨论】:

  • 非常感谢@Yodart。这正是我想要的?
【解决方案3】:

您可以将Navigator 用作您想要制作的特定部分的子代。 如果有的话,我使用WillPopScope 返回上一个屏幕。 并确保使用 GlobalKey() 来分隔每个导航器并给它一个唯一的键。 我的代码:

var keyOne = GlobalKey<NavigatorState>();
var keyTwo = GlobalKey<NavigatorState>();
return Column(
  children: [
    Expanded(
      child: Container(
        child: WillPopScope(
          onWillPop: () async => !await keyOne.currentState.maybePop(),
          child: Navigator(
            key: keyOne,
            onGenerateRoute: (routeSettings) {
              return MaterialPageRoute(
                builder: (context) => ScreenOne(),
              );
            },
          ),
        ),
      ),
    ),
    Expanded(
      child: Container(
        child: WillPopScope(
          onWillPop: () async => !await keyTwo.currentState.maybePop(),
          child: Navigator(
            key: keyTwo,
            onGenerateRoute: (routeSettings) {
              return MaterialPageRoute(
                builder: (context) => ScreenTwo(),
              );
            },
          ),
        ),
      ),
    ),
  ],
);

【讨论】:

    猜你喜欢
    • 2020-10-10
    • 1970-01-01
    • 2021-03-25
    • 2023-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-19
    • 2020-01-14
    相关资源
    最近更新 更多