flutter - flutter :父部件重建后,子部件无法重建吗?

标签 flutter dart

版本:
Flutter版本:1.12.14 channel 开发
Dart版本:2.7.0

问题:
我要写一个Todo应用。当我单击floatbutton时,添加一个新的Todo,但在某些情况下它不能很好地工作。
Scaffold.body中的问题,代码中的细节。

当我使用TodoPage(todoList: _todoList)时,它工作得很好。

提交文本字段时,_pageList.elementAt(_activeIndex)不起作用。

我在提交后发现print('Build Home')打印,但print('Build TodoPage')无法打印。

为什么???

我的代码:

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'));
  }
}


最佳答案

这是合乎逻辑的。

您正在重用Widget的现有实例,并且小部件是不可变的。
因此,框架注意到小部件的实例没有更改,并且没有调用build来优化性能。

您的问题是,您违反了小部件不可更改的规则,这使此优化破坏了您的应用程序。

你做了什么:

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;
  }
}

您应该怎么做:

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;
  }
}

或者,根本不缓存小部件实例。

关于flutter - flutter :父部件重建后,子部件无法重建吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59318208/

相关文章:

firebase - Flutter中的Fcm背景通知

flutter - 在图像上显示图像抖动

charts - Flutter 包失败

具有动态持续时间的 Flutter AnimationController - 错误 : Const variables must be initialized with a constant value

parsing - Dart-如何从 “;”和解析字符串:

Flutter 对象在 initState 之后没有初始化

flutter - Flutter:如何按时间和日期对卡片列表进行排序

flutter - 从另一个有状态的小部件类中获取文本字段数据

flutter - 如何在 flutter 容器的一部分中添加文本?

dart - 如何在 flutter 中截取屏幕外的小部件的屏幕截图?