Flutter中如何将API数据传入SfSlider范围滑块?
问题现象
- 给
SfSlider传入静态值时,滑块可正常拖动交互 - 直接传入API返回的数据时,滑块可触发拖动动作,但无法更新为拖动后的新值,会自动回弹到API响应值对应的位置
- 组件外部声明静态值的方案可正常运行,但业务场景需要使用API返回的参数配置滑块,需要可落地的实现方案
原问题代码:
double _value = 40.0; @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: Center( FutureBuilder( future: propertycall(), // ignore: missing_return builder: (BuildContext context, AsyncSnapshot snapshot) { if (snapshot.hasData) { return SfSlider( shouldAlwaysShowTooltip: true, activeColor: secondarycolor, min: snapshot.data["set-parameters"]["mortgage_interest_rate"]["min_value"], max: snapshot.data["set-parameters"]["mortgage_interest_rate"]["max_value"], value: _value, //issue occur here // value:snapshot.data["set-parameters"]["mortgage_interest_rate"]["default_value"] interval: snapshot.data["set-parameters"]["mortgage_interest_rate"]["steps_value"], showTicks: false, showLabels: false, enableTooltip: true, numberFormat: NumberFormat(), onChanged: (new_value) { setState(() { _value = new_value; // issues!! //API value working but not able to drag slider, //if I give static value from outside of a widget it works // _value=snapshot.data["set-parameters"]["mortgage_interest_rate"]["default_value"] }); }, ); }, }, ), ), ) ); }
问题原因
核心问题有两个:
- 把接口请求方法
propertycall()直接写在FutureBuilder的future参数上,每次setState触发页面重建时,接口请求会重新执行,组件状态被重置- 滑块值
_value硬编码初始值为40.0,没有在接口返回后用接口的默认值初始化,滑块值和接口配置的min/max范围不匹配时,会被SfSlider的边界校验强制回弹到合法位置
修复方案
- 把接口请求逻辑移到
initState生命周期中执行,只在页面初始化时请求一次,避免setState触发重复请求、重置组件状态 - 接口返回成功后,用接口返回的
default_value初始化滑块的本地状态值_value,不要硬编码初始值 - 移除
FutureBuilder,改用加载状态位控制页面展示,滑块的min、max、step参数直接使用缓存的接口返回值,拖动时直接更新本地的_value状态即可 - 接口返回的数值类型参数统一做
.toDouble()转换,避免接口返回int类型时和SfSlider要求的double参数类型不匹配
修复后的完整代码:
// 页面状态变量 double? _sliderValue; Map? _sliderConfig; bool _pageLoading = true; @override void initState() { super.initState(); // 初始化时只请求一次接口配置 _fetchSliderConfig(); } Future<void> _fetchSliderConfig() async { final apiResult = await propertycall(); setState(() { _sliderConfig = apiResult["set-parameters"]["mortgage_interest_rate"]; // 用接口默认值初始化滑块 _sliderValue = _sliderConfig!["default_value"].toDouble(); _pageLoading = false; }); } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: Center( child: _pageLoading // 配置加载中展示loading ? const CircularProgressIndicator() : SfSlider( shouldAlwaysShowTooltip: true, activeColor: secondarycolor, min: _sliderConfig!["min_value"].toDouble(), max: _sliderConfig!["max_value"].toDouble(), value: _sliderValue!, interval: _sliderConfig!["steps_value"].toDouble(), showTicks: false, showLabels: false, enableTooltip: true, numberFormat: NumberFormat(), onChanged: (newValue) { setState(() { _sliderValue = newValue; }); }, ) ) ) ); }
补充:如果需要在滑块拖动结束后把值同步给后端,在onChangeEnd回调中调用接口提交即可,不要在拖动过程中的onChanged回调里触发接口请求,否则也会导致滑块回弹。
内容的提问来源于stack exchange,提问作者Gnanaprakash
相关产品推荐
相关产品推荐

