我正在开发Flutter Web应用程序。
目标是在大多数路由屏幕中重复使用相同的布局屏幕小部件(抽屉,应用栏(。
我尝试创建一个新的脚手架类并将正文小部件添加到每个屏幕。
问题是每次我导航到新屏幕时。在小部件树上创建了一个新的(MyScaffold(。所以这对性能不利。
我也尝试使用嵌套路由器,问题是嵌套路由器不受url支持,我无法通过键入URL导航到屏幕。
有没有其他适当的方法来解决这个问题。
谢谢
添加代码示例:
import 'package:flutter/material.dart';
void main() => runApp(AppWidget());
class AppWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: '/',
routes: {
'/': (context) => FirstScreen(),
'/second': (context) => SecondScreen(),
},
);
}
}
class FirstScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('First Screen'),
),
body: Center(
child: RaisedButton(
child: Text('Launch screen'),
onPressed: () {
Navigator.pushReplacementNamed(context, '/second');
},
),
),
);
}
}
class SecondScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Second Screen"),
),
body: Center(
child: RaisedButton(
onPressed: () {
Navigator.pushReplacementNamed(context, '/');
},
child: Text('Go back!'),
),
),
);
}
}
我会尝试更好地解释这个问题。
如您所见,第一屏幕和第二屏幕具有完全相同的小部件树结构。但是每次颤振都会删除屏幕小部件并创建一个新的。
我还尝试更改代码以创建新的MyScaffold并重用相同的Widget类:
class AppWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: '/',
routes: {
'/': (context) => MyScallfold(
bodyWidget: FirstScreen(),
),
'/second': (context) => MyScallfold(
bodyWidget: SecondScreen(),
),
},
);
}
}
class FirstScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return RaisedButton(
onPressed: () {
Navigator.pushReplacementNamed(context, '/second');
},
child: Text('To Screen 2!'),
);
}
}
class SecondScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return RaisedButton(
onPressed: () {
Navigator.pushReplacementNamed(context, '/');
},
child: Text('To Screen 1!'),
);
}
}
class MyScallfold extends StatelessWidget {
Widget bodyWidget;
MyScallfold({this.bodyWidget});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('WebAppTest'),
),
body: bodyWidget,
);
}
}
巴士 我注意到每次使用导航时,树的所有小部件都会重建(渲染对象 #id 被更改(
那么是否可以在颤振中重复使用相同的渲染对象(AppBar,RichText(来优化性能?
快速的答案是否定的,反正还没有。目前,当您使用导航器时,它会刷新页面并重建完整视图。
目前在 Flutter Web 上最有效的方法是在带有 SingleTickerProviderStateMixin 的有状态小部件中使用带有 TabBar View 的 TabController。
它只加载屏幕上的小部件,但不需要重新加载页面来查看其他页面。您的示例如下所示(我添加了动画以过渡到下一页,但您可以将其删除(:
import 'package:flutter/material.dart';
TabController tabController;
class MainScreen extends StatefulWidget {
@override
_MainScreenState createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> with SingleTickerProviderStateMixin {
int activeTab = 0;
@override
void initState() {
tabController = TabController(length: 3, vsync: this, initialIndex: 0)
..addListener(() {
setState(() {
activeTab = tabController.index;
});
});
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('WebAppTest'),
),
body: Expanded(
child: TabBarView(
controller: tabController,
children: <Widget>[
FirstScreen(), //Index 0
SecondScreen(), //Index 1
ThirdScreen(), //Index 2
],
),
),
);
}
}
class FirstScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return RaisedButton(
onPressed: () {
tabController.animateTo(2);
},
child: Text('To Screen 3!'),
);
}
}
class SecondScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return RaisedButton(
onPressed: () {
tabController.animateTo(0);
},
child: Text('To Screen 1!'),
);
}
}
class ThirdScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return RaisedButton(
onPressed: () {
tabController.animateTo(1);
},
child: Text('To Screen 2!'),
);
}
}