由于各种原因,有时会再次调用小部件的build方法。
我知道这种情况会发生,因为一个父母更新了。但这会造成不良影响。
导致问题的典型情况是这样使用FutureBuilder:
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: httpCall(),
builder: (context, snapshot) {
// create some layout here
},
);
}
在本例中,如果再次调用构建方法,它将触发另一个HTTP请求。这是不受欢迎的。
考虑到这一点,如何处理不需要的构建?有什么方法可以阻止构建调用吗?
避免不必要的重建(通常是通过调用setState()来只更新特定的小部件而不刷新整个页面而引起的)的最简单方法之一是删除这部分代码,并将其包装为另一个有状态类中的独立小部件。
例如,在下面的代码中,通过按下FAB按钮,父页面的Build方法被反复调用:
import 'package:flutter/material.dart';
void main() {
runApp(TestApp());
}
class TestApp extends StatefulWidget {
@override
_TestAppState createState() => _TestAppState();
}
class _TestAppState extends State<TestApp> {
int c = 0;
@override
Widget build(BuildContext context) {
print('build is called');
return MaterialApp(home: Scaffold(
appBar: AppBar(
title: Text('my test app'),
),
body: Center(child:Text('this is a test page')),
floatingActionButton: FloatingActionButton(
onPressed: (){
setState(() {
c++;
});
},
tooltip: 'Increment',
child: Icon(Icons.wb_incandescent_outlined, color: (c % 2) == 0 ? Colors.white : Colors.black)
)
));
}
}
但是如果你将FloatingActionButton小部件分离到另一个具有自己生命周期的类中,setState()方法不会导致父类Build方法重新运行:
import 'package:flutter/material.dart';
import 'package:flutter_app_mohsen/widgets/my_widget.dart';
void main() {
runApp(TestApp());
}
class TestApp extends StatefulWidget {
@override
_TestAppState createState() => _TestAppState();
}
class _TestAppState extends State<TestApp> {
int c = 0;
@override
Widget build(BuildContext context) {
print('build is called');
return MaterialApp(home: Scaffold(
appBar: AppBar(
title: Text('my test app'),
),
body: Center(child:Text('this is a test page')),
floatingActionButton: MyWidget(number: c)
));
}
}
和MyWidget类:
import 'package:flutter/material.dart';
class MyWidget extends StatefulWidget {
int number;
MyWidget({this.number});
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
@override
Widget build(BuildContext context) {
return FloatingActionButton(
onPressed: (){
setState(() {
widget.number++;
});
},
tooltip: 'Increment',
child: Icon(Icons.wb_incandescent_outlined, color: (widget.number % 2) == 0 ? Colors.white : Colors.black)
);
}
}
Flutter也有ValueListenableBuilder<T>类。它允许您只重新构建您的目的所必需的一些小部件,而跳过昂贵的小部件。
你可以在这里看到ValueListenableBuilder颤振文档
或者只是下面的示例代码:
return Scaffold(
appBar: AppBar(
title: Text(widget.title)
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('You have pushed the button this many times:'),
ValueListenableBuilder(
builder: (BuildContext context, int value, Widget child) {
// This builder will only get called when the _counter
// is updated.
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text('$value'),
child,
],
);
},
valueListenable: _counter,
// The child parameter is most helpful if the child is
// expensive to build and does not depend on the value from
// the notifier.
child: goodJob,
)
],
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.plus_one),
onPressed: () => _counter.value += 1,
),
);
我只是想分享我的经验,不需要的小部件构建主要是由于上下文,但我发现了一种非常有效的方法
路线流行/推动
因此,您需要使用Navigator.pushReplacement(),以便上一页的上下文与即将到来的页面没有关系
使用Navigator.pushReplacement()从第一页导航到第二页
在第二页我们同样需要使用navigator。pushreplacement ()
在appBar中我们添加了-
领导:IconButton (
图标:图标(Icons.arrow_back),
onPressed:() {
Navigator.pushReplacement (
背景下,
RightToLeft(页面:MyHomePage ()),
);
},
)
通过这种方式,我们可以优化应用程序