如何防止重建 PageView 的 StatelessWidget 子项



我创建了简单的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.buildSecondPage.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"),
),
);
}
}
  • 扩展AutomaticKeepAliveClientMixinStatefullWidget创建的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"),
),
);
}
  • 用返回值覆盖wantKeepAlivegettertrue
@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架构

它将在远离ViewViewModel保存您的状态,因此您的 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,
],
)

祝你好运。

最新更新