[英]flutter: child widget not rebuilt after parent rebuild
Version:版本:
Flutter-Version: 1.12.14 channel dev Flutter 版本:1.12.14 通道开发
Dart-Version: 2.7.0 Dart 版本:2.7.0
Question:题:
I wan write a Todo App.我想写一个 Todo 应用程序。 when i click floatbutton add a new Todo, but in some cases its not work well.
当我点击浮动按钮添加一个新的 Todo 时,但在某些情况下它不能很好地工作。
The problem in Scaffold.body
, detials in code. Scaffold.body
的问题,代码中的细节。
it work well when i use TodoPage(todoList: _todoList)
.当我使用
TodoPage(todoList: _todoList)
时它运行良好。
_pageList.elementAt(_activeIndex)
is not work when i submit textfield .当我提交 textfield 时
_pageList.elementAt(_activeIndex)
不起作用。
I found the print('Build Home')
print after submit but print('Build TodoPage')
not print.我发现提交后
print('Build Home')
打印但print('Build TodoPage')
不打印。
why???为什么???
My Code:我的代码:
import 'package:flutter/material.dart';
void main() => runApp(App());
class App extends StatelessWidget{
@override
Widget build(BuildContext context){
return MaterialApp(
title: 'TodoList',
home: Home(),
);
}
}
class Home extends StatefulWidget{
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home>{
List<String> _todoList = ['a', 'b', 'c'];
TextEditingController _controller;
List<Widget> _pageList;
int _activeIndex;
Widget _curPage;
@override
void initState(){
super.initState();
_activeIndex = 0;
_pageList = [TodoPage(todoList: _todoList,), OtherPage()];
_curPage = _pageList[_activeIndex];
_controller = TextEditingController();
}
@override
Widget build(BuildContext context){
print('build Home');
return Scaffold(
appBar: AppBar(title: Text('Todo'),),
body: _pageList.elementAt(_activeIndex), // this is not work
// body: TodoPage(todoList: _todoList,), // this is work well
floatingActionButton: FloatingActionButton(
onPressed: _openDlg,
child: Icon(Icons.add),
),
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(icon: Icon(Icons.list), title: Text('Todo')),
BottomNavigationBarItem(icon: Icon(Icons.favorite), title: Text('Other')),
],
currentIndex: _activeIndex,
selectedItemColor: Colors.blue,
onTap: _onMenuTap,
),
);
}
_onMenuTap(int index){
setState(() {
_activeIndex = index;
});
}
_openDlg(){
showDialog(
context: context,
builder: (BuildContext context){
return SimpleDialog(
children: <Widget>[
TextField(
controller: _controller,
),
SimpleDialogOption(
child: FloatingActionButton(child: Text('submit'), onPressed: _addTodo,),
)
],
);
}
);
}
_addTodo(){
print(_controller.text);
setState(() {
_todoList.add(_controller.text);
});
}
}
class TodoPage extends StatefulWidget{
TodoPage({Key key, this.todoList}): super(key: key);
List<String> todoList;
_TodoPageState createState() => _TodoPageState();
}
class _TodoPageState extends State<TodoPage>{
@override
void initState(){
super.initState();
}
@override
Widget build(BuildContext context){
print('build TodoPage');
return Column(
children: _buildTodoList(),
);
}
List <Widget> _buildTodoList(){
return widget.todoList.map((todo){
return Text(todo, style: TextStyle(fontSize: 30),);
}).toList();
}
}
class OtherPage extends StatelessWidget{
@override
Widget build(BuildContext context){
return Center(child: Text('Other Page'));
}
}
That is logical.这是合乎逻辑的。
You are reusing an existing instance of a Widget
, and widgets are immutable.您正在重用
Widget
的现有实例,并且小部件是不可变的。 As such, the framework notice that the instance of the widget did not change and doesn't call build
to optimize performances.因此,框架注意到小部件的实例没有改变,并且不会调用
build
来优化性能。
Your problem being, you violated the rule of widgets being immutable, which makes this optimization break your app.你的问题是,你违反了小部件不可变的规则,这使得这个优化破坏了你的应用程序。
What you did:你做了什么:
class MyState extends State<MyStatefulWidget> {
SomeWidget myWidget = SomeWidget()..someProperty = "initial value";
void onSomething() {
setState(() {
myWidget.someProperty = "new value";
});
}
@override
Widget build(BuildContext context) {
return myWidget;
}
}
What you should instead do:你应该做什么:
class MyState extends State<MyStatefulWidget> {
SomeWidget myWidget = SomeWidget(someProperty: "initial value");
void onSomething() {
setState(() {
myWidget = SomeWidget(someProperty: "new value");
});
}
@override
Widget build(BuildContext context) {
return myWidget;
}
}
Alternatively, just don't cache the widget instance at all.或者,根本不缓存小部件实例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.