来自父窗口小部件的setState不会更新子窗口的值

问题描述 投票:0回答:1

我有一个StatefulWidget,其中有一个ListView包含几个子窗口小部件。

其中一个孩子是包含一些物品的GridView

我想要实现的是当从Parent小部件按下按钮时重建这个GridView子节点。该按钮位于Parent小部件的bottomNavigationBar中。

但是,当我按下按钮时,它应该转到_resetFilter()方法,该方法有效。但setState()似乎没有更新Child小部件中的GridView build()方法。

class ParentState extends State<Parent> {

  // removed for brevity

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(...),
      bottomNavigationBar: BottomAppBar(
        child: new Row(
          children: <Widget>[
            Padding(
                padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 5.0),
                child: SizedBox(
                  onPressed: () {
                    _resetFilter();
                  },
                )
            ),
          ],
        ),
      ),
      body: Container(
        child: Form(
            key: _formKey,
            child: ListView(
              children: <Widget>[
                Column(
                  children: <Widget>[
                    Container(
                      child: Column(
                        children: <Widget>[
                          Container(...), // this works
                          Column(...),
                          Container(...), // this works
                          Container( 
                            child: GridView.count(
                              // ...
                              children:
                                  List.generate(oriSkills.length, (int i) {

                                bool isSkillExist = false;

                                if (_selectedSkills.contains(rc.titleCase)) {
                                  isSkillExist = true;
                                } else {
                                  isSkillExist = false;
                                }
                                return Child( // this doesn't work
                                  id: oriSkills[i]['id'],
                                  name: oriSkills[i]['description'],
                                  skillSelect: isSkillExist, // this boolean showed correct value from the above logic
                                  onChange: onSkillChange,
                                );
                              }),
                            ),
                          ),
                        ],
                      ),
                    )
                  ],
                )
              ],
            )),
      ),
    );
  }

  void _resetFilter() {
    setState(() {
      _theValue = 0.0;
      searchC.text = "";
      _selectedSkills = []; // this is the variable that I'd like the GridView to recreate from.
    });
  }
}

我试图在Child小部件中打印一个字段名称,但它始终显示旧值而不是新值。

即使在按下按钮后,它也会将正确的值传递给qazxsw poi。

ChildState

如何在按下重置按钮后更新子窗口小部件以从父窗口小部件获取更新的值?

dart flutter
1个回答
1
投票

您可能希望将值传递给实际的Child类。不是它的状态。 一旦父级重建,该课程将重建。所以新的价值观将会反映出来。

因此,您的class ChildState extends State<Child> { final String name; final MyCallbackFunction onChange; bool skillSelect; double size = 60.0; ChildState({this.name, this.skillSelect, this.onChange}); @override void initState() { super.initState(); } @override void dispose() { super.dispose(); } void setSkillLevel() { setState(() { if (skillSelect) { skillSelect = false; onChange(name, false); } else { skillSelect = true; onChange(name, true); } }); } Color _jobSkillSelect(bool select) { print(select); // always print old state instead of new state return select ? Color(MyColor.skillLvlOne) : Color(MyColor.skillDefault); } @override Widget build(BuildContext context) { return Container( child: Column(children: <Widget>[ InkResponse( onTap: setSkillLevel, child: Container( height: size, width: size, decoration: BoxDecoration( image: DecorationImage( colorFilter: ColorFilter.mode(_jobSkillSelect(skillSelect), BlendMode.color), ), ), )), ])); } } 实现应该看起来像这样(不要忘记将Child类型替换为您的自定义函数。

onChange

在这种情况下,Child不再负责管理其class Child extends StatefulWidget { final String name; final Function(void) onChange; final bool skillSelect; final double size; final Function(bool) onSkillLevelChanged; const Child({Key key, this.name, this.onChange, this.skillSelect, this.size, this.onSkillLevelChanged}) : super(key: key); @override _ChildState createState() => _ChildState(); } class _ChildState extends State<Child> { Color _jobSkillSelect(bool select) { print(select); // always print old state instead of new state return select ? Color(MyColor.skillLvlOne) : Color(MyColor.skillDefault); } @override Widget build(BuildContext context) { return Container( child: Column( children: <Widget>[ InkResponse( onTap: () { if (widget.onSkillLevelChanged != null) { widget.onSkillLevelChanged(!widget.skillSelect); } }, child: Container( height: widget.size, width: widget.size, decoration: BoxDecoration( image: DecorationImage( colorFilter: ColorFilter.mode(_jobSkillSelect(widget.skillSelect), BlendMode.color), ), ), )), ], ), ); } } 财产。它只是在其父母身上调用skillSelect。然后父级使用新的skillSelect布尔值构建。

所以你可以像这样使用这个孩子:

Function
© www.soinside.com 2019 - 2024. All rights reserved.