我创建了简单的PageView应用程序来测试多个页面。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
final firstPage = FirstPage(key: Key("FirstPage"));
final secondPage = SecondPage(key: Key("SecondPage"));
debugPrint("_MyHomePageState.build");
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: PageView(
children: <Widget>[
firstPage,
secondPage,
],
),
);
}
}
class FirstPage extends StatelessWidget {
FirstPage({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
debugPrint("FirstPage.build");
return Container(
child: Center(
child: Text("First Page"),
),
);
}
}
class SecondPage extends StatelessWidget {
SecondPage({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
debugPrint("SecondPage.build");
return Container(
child: Center(
child: Text("Second Page"),
),
);
}
}
即使认为_MyHomePageState.build只显示过一次,FirstPage.build和SecondPage.build也印在每次页面更改上。
我想防止不必要的页面绘制,我该如何实现?
你可以通过使用来实现这一点
1.const
关键字
让你的小部件接受
const
:类 FirstPage 扩展 StatelessWidget { const FirstPage({Key key}( : super(key: key(;
@override Widget build(BuildContext context) { debugPrint("FirstPage.build"); return Container( child: Center( child: Text("First Page"), ), ); }
}
并用
const
关键字调用它:return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: PageView( children: <Widget>[ const firstPage(), const secondPage(), ], ), );
阿拉伯数字。AutomaticKeepAliveClientMixin
- 将您的
StatelessWidget
转换为StatefullWidget
。
class FirstPage extends StatefulWidget {
FirstPage({Key key}) : super(key: key);
@override
_FirstPageState createState() => _FirstPageState();
}
class _FirstPageState extends State<FirstPage> {
@override
Widget build(BuildContext context) {
debugPrint("FirstPage.build");
return Container(
child: Center(
child: Text("First Page"),
),
);
}
}
- 扩展
AutomaticKeepAliveClientMixin
StatefullWidget
创建的State
。
class _FirstPageState extends State<FirstPage> with AutomaticKeepAliveClientMixin {
- 在
build
方法上调用super
。
@override
Widget build(BuildContext context) {
super.build(context);
debugPrint("FirstPage.build");
return Container(
child: Center(
child: Text("First Page"),
),
);
}
- 用返回值覆盖
wantKeepAlive
gettertrue
。
@override
bool get wantKeepAlive => true;
然后你的小部件树不会处理这个小部件,所以它不会一遍又一遍地重建。
代码示例:
class FirstPage extends StatefulWidget {
FirstPage({Key key}) : super(key: key);
@override
_FirstPageState createState() => _FirstPageState();
}
class _FirstPageState extends State<FirstPage>
with AutomaticKeepAliveClientMixin {
@override
Widget build(BuildContext context) {
super.build(context);
debugPrint("FirstPage.build");
return Container(
child: Center(
child: Text("First Page"),
),
);
}
@override
bool get wantKeepAlive => true;
}
3. 使用您喜欢的任何State-management
解决方案MVVM
架构
它将在远离View
ViewModel
保存您的状态,因此您的 UI 可以随时重建自己,而不必担心您的State
,因为ViewModel
仍然相同。
你应该总是想象你的build((方法(对于StatefulWidget和StatelessWidget(每秒被调用60次,所以它们应该是简单和幂等的。 其他任何东西都应该移动到 StatefulWidget initState(( 和 friends 中。
这很容易!
pageController
可以帮助您。
就在你_MyHomePageState
声明final pageController = PageController(keepPage: false);
在你的PageView
PageView(
controller: pageController,
children: <Widget>[
firstPage,
secondPage,
],
)
祝你好运。