如何在不创建新的小部件树分支的情况下重复使用相同的布局屏幕



我正在开发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!'),
);
}
}

最新更新