Это означает, что, как правило, должен быть один Scaffold
для каждой страницы (точнее, для каждого Route
/ screen), и что вы не должны вкладывать Scaffold
s.
Навигация между экранами
Например, посмотрите на этот фрагмент, который вы можете запустить в 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!'),
),
),
);
}
}
Здесь вы можете видите, есть две разные страницы / Route
s / screens, и у каждой есть свой Scaffold
. Мы перемещаемся назад и вперед, используя Navigator
, и поэтому наши страницы добавляются в стек, один Scaffold
поверх другого. Это нормально.
Если позже, разве это не означает, что общий AppBar и BottomBar перерисовываются при каждой навигации?
Да, но это так именно то, что мы хотим, когда мы делаем два отдельных экрана, каждый со своим собственным 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: () {},
),
),
),
);
}
}
Здесь мы вкладываем два Scaffold
s, и, как вы можете видеть, вторая панель приложения рисуется под первой панелью приложения. Это не лучший подход для вкладок или вложенных переходов. Если вы хотите перемещаться внутри тела 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),
],
),
),
),
);
}
}
Как видите, мы использовали только один Scaffold
, так как на самом деле мы имеем дело только с одним экраном. Просто так получается, что мы хотим показывать контентные страницы и перемещаться внутри тела Scaffold
.
Заключение
Как общее правило: используйте только один Scaffold
на Route
/ экран. Используйте только один Scaffold
с виджетами, такими как TabController
или IndexedStack
, для навигации по содержимому внутри тела одного экрана.