You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter自定义DropDown Picker切换时widget不渲染、默认值不更新问题

问题解决方案

问题根源

Flutter的Widget树Diff机制默认会对同一位置、同一类型的Widget复用对应的State对象。你从Minutes切换到Hours时,子组件返回的都是CustomDropDown类型,且在Widget树中的位置没有发生变化,因此原来的_CustomDropDownState不会被销毁重建,仅在组件第一次初始化时执行的initState不会重新触发,后续新传入的defaultVal无法赋值给内部的chosenValue,就会出现保留旧选中值的问题。

解决方法

两种方案按需选择即可:

方案1:给子CustomDropDown添加唯一Key(最简便)

在repeatEveryWidget方法中返回CustomDropDown时,传入和当前下拉类型绑定的唯一Key,告诉Flutter这是两个不同的组件需要销毁重建:

return CustomDropDown(
  key: Key(isMinutesWidget ? "minute_dropdown" : "hour_dropdown"), // 新增此行
  isExpanded: false,
  dropDownList: dropDownList,
  defaultVal: isMinutesWidget ? defaultMinuteSelected : defaulHourSelected,
  dropDownType: DropDownType.DROPDOWN_WITH_ARROW,
  selectedItem: (String selectedVal, DropDownsType dropDownId) {
    if (isMinutesWidget) {
      defaultMinuteSelected = selectedVal;
    } else {
      defaulHourSelected = selectedVal;
    }
  },
  customDropDownId: DropDownsType.CustomId,
);

切换Minutes和Hours时Key发生变化,Flutter会销毁旧的State实例,重建新的CustomDropDown,自动加载对应新的defaultVal。该方案适合两个下拉选项完全独立的场景,无历史数据残留。

方案2:在CustomDropDown的State中监听属性变化更新值

如果你不需要重建组件想要更好的性能,可以重写didUpdateWidget生命周期方法,当外部传入的defaultVal变化时,同步更新内部的chosenValue:
在_CustomDropDownState类中添加以下代码:

@override
void didUpdateWidget(covariant CustomDropDown oldWidget) {
  super.didUpdateWidget(oldWidget);
  // 当外部传入的defaultVal变化时,同步更新内部选中值
  if (widget.defaultVal != oldWidget.defaultVal) {
    setState(() {
      chosenValue = widget.defaultVal;
    });
  }
}

内容的提问来源于stack exchange,提问作者Ravi Parmar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 07:36:03