Flutter 应用程序中每个页面的多个脚手架

dor*_*ora 22 navigation android scaffolding material-design flutter

API 文档:https : //api.flutter.dev/flutter/material/Scaffold-class.html说:

Scaffold 被设计为 MaterialApp 的单一顶级容器,通常不需要嵌套脚手架。例如,在选项卡式 UI 中,bottomNavigationBar 是一个 TabBar 而主体是一个 TabBarView,您可能会想使每个选项卡栏视图成为具有不同标题的 AppBar 的脚手架。最好为更新 AppBar 的 TabController 添加一个监听器。

这是否意味着 Material App 下只需要一个 Scaffold 或每个页面一个单一的父 Scaffold。如果是第一个,我们如何导航?如果它的后,并不意味着通用AppBarBottomBar每个导航得到重新渲染?最佳做法是什么。

dro*_*gel 30

这意味着,通常,Scaffold每个页面都应该有一个(更准确地说,每个Route/screen),并且您不应该嵌套Scaffolds。

在屏幕之间导航

例如,看看你可以在DartPad 中运行的这个片段:

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    title: 'Navigation Basics',
    home: FirstRoute(),
  ));
}

class FirstRoute extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('First Route'),
      ),
      body: Center(
        child: RaisedButton(
          child: Text('Open route'),
          onPressed: () {
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => SecondRoute()),
            );
          },
        ),
      ),
    );
  }
}

class SecondRoute extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Second Route"),
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: Text('Go back!'),
        ),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

在这里,您可以看到有两个不同的页面Route/屏幕/屏幕,每个页面都有自己的Scaffold. 我们使用 来回导航Navigator,因此我们的页面被添加到堆栈中,一个Scaffold在另一个之上。那没关系。

如果它晚了,是不是意味着公共 AppBar 和 BottomBar 会在每个导航上重新呈现?

是的,但是当我们制作两个独立的屏幕时,这正是我们想要的,每个屏幕都有自己的Scaffold.

在 Scaffold / 嵌套导航的主体内导航

另一方面,看看这个例子:

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    title: 'Navigation Basics',
    home: FirstRoute(),
  ));
}

class FirstRoute extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('First Route'),
      ),
      body: Scaffold(
        body: Center(
          child: RaisedButton(
            child: Text('Open route'),
            onPressed: () {},
          ),
        ),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

在这里,我们嵌套了两个Scaffolds,并且如您所见,第二个应用栏被绘制在第一个应用栏下方。这不是选项卡式或嵌套导航的最佳方法。如果您想在 a 的主体内导航Scaffold,并根据内容更改应用栏,则首选使用TabControllers,例如DefaultTabController。看看这个例子:

import 'package:flutter/material.dart';

void main() {
  runApp(TabBarDemo());
}

class TabBarDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: DefaultTabController(
        length: 3,
        child: Scaffold(
          appBar: AppBar(
            bottom: TabBar(
              tabs: [
                Tab(icon: Icon(Icons.directions_car)),
                Tab(icon: Icon(Icons.directions_transit)),
                Tab(icon: Icon(Icons.directions_bike)),
              ],
            ),
            title: Text('Tabs Demo'),
          ),
          body: TabBarView(
            children: [
              Icon(Icons.directions_car),
              Icon(Icons.directions_transit),
              Icon(Icons.directions_bike),
            ],
          ),
        ),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

如您所见,我们只使用了一个Scaffold,因为我们实际上只处理一个屏幕。碰巧我们想要显示内容页面并在Scaffold.

结论

作为一般经验法则:Scaffold每个Route/screen只使用一个。仅将一个Scaffold与小部件一起使用,例如TabControllerIndexedStack来导航单个屏幕主体内的内容。

  • 如果出现底部导航栏该怎么办。我有一个类,我正在返回脚手架,并且对于它的主体,我正在传递页面数组,其中每个页面还包含它自己的脚手架。可以吗?它有效,但我不确定这是否是正确的方法 (5认同)
  • 不需要“钥匙”吗?尝试学习使用密钥的最佳实践,当我注意到此页面上没有提及或使用密钥时。 (2认同)
  • 不适用于抽屉导航。感觉 Flutter 好像不完整。 (2认同)