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
相关产品推荐
相关产品推荐

