Flutter 如何在小部件方法中将变量作为状态传递?

Flutter 如何在小部件方法中将变量作为状态传递?,flutter,dart,state-management,Flutter,Dart,State Management,我有一段代码,它在flatter中呈现一个下拉按钮。我需要几个下拉列表,所以我将其提取到一个方法中,以便为我需要的每个实例调用。在其中,我传递所选值的状态变量以及所有选项。在DropdownButton内部,我有更新DropdownButtononChanged方法中选择的的方法 因此,当我调用该方法而不是就地使用它时,问题就出现了,因为onChanged和onClear的函数不会重建小部件,因为它们不会在调用下拉方法之外更新状态变量。最好的方法是什么?如果我从外部传入函数,它确实可以工作,但是

我有一段代码,它在flatter中呈现一个
下拉按钮。我需要几个下拉列表,所以我将其提取到一个方法中,以便为我需要的每个实例调用。在其中,我传递所选值的状态变量以及所有选项。在DropdownButton内部,我有更新
DropdownButton
onChanged
方法中选择的
的方法

因此,当我调用该方法而不是就地使用它时,问题就出现了,因为onChanged和onClear的函数不会重建小部件,因为它们不会在调用下拉方法之外更新状态变量。最好的方法是什么?如果我从外部传入函数,它确实可以工作,但是我必须复制一些代码。我是否应该将其重写为一个
StatefulWidget

DropdownButton myDropdown(
  String selected,
  List<dynamic> options, {
  Function onChanged,
  Function onClear,
}) {
  return DropdownButton<String>(
    value: selected,
    // onChanged: (String newValue) { // Not working
    //   setState(() {
    //     selected = newValue;
    //   });
    // },
    onChanged: onChanged,
    selectedItemBuilder: (BuildContext context) {
      return options?.map<Widget>((dynamic item) {
        return Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: <Widget>[
            Text(item),
            IconButton(
              icon: Icon(Icons.clear),
              // onPressed: () { // Not working
              //   setState(() {
              //     selected = null;
              //   });
              // },
              onPressed: onClear,
            ),
          ],
        );
      })?.toList() ?? [];
    },
    items: options?.map<DropdownMenuItem<String>>((dynamic value) {
      return DropdownMenuItem<String>(
        value: value,
        child: Text(value),
      );
    })?.toList() ?? [],
  );
}
dropdown按钮我的下拉列表(
选择字符串,
列出选项{
功能一旦改变,
函数onClear,
}) {
返回下拉按钮(
值:选中,
//onChanged:(字符串newValue){//不工作
//设置状态(){
//所选=新值;
//   });
// },
一旦改变:一旦改变,
selectedItemBuilder:(BuildContext){
返回选项?.map((动态项){
返回行(
mainAxisAlignment:mainAxisAlignment.spaceBetween,
儿童:[
文本(项目),
图标按钮(
图标:图标(图标。清除),
//onPressed:(){//不工作
//设置状态(){
//选中=空;
//   });
// },
onPressed:onClear,
),
],
);
})?.toList()??[];
},
项目:选项?.map((动态值){
返回下拉菜单项(
价值:价值,
子项:文本(值),
);
})?.toList()??[],
);
}

(在这个项目中,我确实使用provider进行状态管理,但我不确定它是否真的与这个问题相关。)

在父类中的某个地方定义所选的
,从中调用DropdownButton

var selected;
现在像这样写下拉按钮-

DropdownButton(
 selected,
 [whatever],
 onChanged: (newValue) {
    selected = newValue;
    setState(() {});
 } 
 onClear: () {
  selected = null;
  setState(() {}); 
}
)


因此,一旦调用onChanged或onClear,它将更改
选定的
值,并用新选定的值刷新小部件。

解决方案是将
下拉按钮
的值包装在
StatefulWidget
中,以管理其状态

我提供了一个自定义
小部件的示例,它可以实现这一点,与原始代码的精神相同


进口“包装:颤振/材料.省道”;
///托管的[DropdownButton]初始化为[selected],并带有可能的值
///[选项]。
///
///所选值在下拉项单击时更新,并触发[onChanged]
///回拨。
///
///“x”清除按钮出现在所有菜单项上,并将选定项设置为
///null,同时也触发[onClear]回调。
类SuperDropdown扩展了StatefulWidget{
超级下拉列表({
@需要此选项。已选择,
@需要此选项,
这一点很清楚,
一旦改变了,
});
更改后的最终函数(字符串s);
final Function()onClear;
最后清单选择;
选择最终字符串;
@凌驾
_SuperDropdownState createState();
}
类_SuperDropdownState扩展状态{
选择字符串;
List get items=>widget.options
.map((i)=>下拉菜单项(
价值观:我,
儿童:文本(i),
))
.toList();
更改后无效(字符串值){
设置状态(()=>selected=value);
widget.onChanged?.call(值);
}
void onClear(){
设置状态(()=>selected=null);
widget.onClear?.call();
}
List itemBuilder(BuildContext上下文)=>widget.options
.map((i)=>
行(mainAxisAlignment:mainAxisAlignment.spaceBetween,子项:[
案文(i),
图标按钮(
图标:图标(图标。清除),
onPressed:onClear,
),
]))
.toList();
@凌驾
void initState(){
super.initState();
selected=widget.selected;
}
@凌驾
小部件构建(BuildContext上下文)=>DropdownButton(
值:选中,
项目:项目,,
一旦改变:一旦改变,
选择EditEmBuilder:itemBuilder,
);
}
void main()=>runApp(
材料聚丙烯(
家:脚手架(
正文:中(
子:列(
子项:[“abc”、“def”]
.map((字母)=>超级下拉列表(
选定:字母。子字符串(0,1),
选项:字母。拆分(“”),
一旦更改:(s)=>
打印(“下拉$letters更改为$s”),
onClear:()=>打印(“已清除下拉$letters”),
))
.toList(),
),
),
),
),
);

由于原始问题希望将状态管理封装在helper函数中,因此在他们的示例中没有一个点可以提供所选的
变量。请参考我的回答,了解如何通过创建自定义小部件来封装状态管理