在 Flutter 中管理动态小部件状态的正确方法

Correct way to manage state on dynamic widgets in Flutter

我在 sqlite 中有一个类别列表,我在 streambuilder 中获取了这些行,然后,我创建了一个开关小部件列表。在每个开关小部件 ontoggle 事件中,我更改源值并调用 setState 方法,但是,这会导致构建事件的执行并重置所有开关小部件值。之后,我更改了代码以将所有小部件存储在一个变量中,如果小部件存在,则在 streambuild 中,return 小部件列表,这几乎可以正常工作,这会更新源中的小部件值,但是,小部件看起来像如果它们是假的。

有人知道吗?

此致

           StreamBuilder<List<Category>>(   <--- this code is in build event
              stream: _catBloc.categoriesStream,
              builder: (BuildContext context, AsyncSnapshot<List<Category>> snapshot) {
                if(!snapshot.hasData) {
                  return Container(
                    height: _size.height,
                    width: _size.width,
                    child: Center(
                      child: CircularProgressIndicator(),
                    ),
                  );
                } else if(_categoriesLinked.isEmpty){ <-- this is a map with the list of id and name
                  column = _createCategories(snapshot.data, widthSwitch);
                  return column;
                 } else {
                   return column;
                 }
              },
            ),


Container(  <-- this is inside _createCategories method
      width: width,
      child: Row(
        children: [
          FlutterSwitch(
            width: _size.width * 0.06,
            height: _size.height * 0.02,
            toggleSize: 20.0,
            value: _categoriesLinked[e.id],
            showOnOff: false,
            padding: 2.0,
            activeColor: Color.fromRGBO(88, 203, 143, 0.25),
            inactiveColor: Color.fromRGBO(224, 233, 240, 0.50),
            activeToggleColor: Color.fromRGBO(88, 203, 143, 1.0),
            inactiveToggleColor: Color.fromRGBO(78, 88, 96, 0.50),
            onToggle: (val) => setState(() {
              _categoriesLinked[e.id] = val;
            }),
          ),
          SizedBox(width: _size.width * 0.01,),
          Flexible(child: Text("${ e.id}. ${ e.name}"))
        ]
      ),
    )

在这种情况下,您应该重构您的代码,以便将开关创建为另一个小部件,使它们只重建自己。

对于开关的状态,您可以简单地使用 GlobalKey<MySwitchState> 从父级获取它,以便在 onPressed 方法期间访问子级状态,例如:mySwitchKey.currentState

您绝对应该避免在方法内部构建有状态小部件。如果您觉得需要一种方法,请创建一个新的小部件。