当一个开关在FutureBuilder中的属性发生变化时,我怎样才能使它正确地 "动画化"?

问题描述 投票:0回答:1

我有一个开关,可以改变数据库中的一个值。FutureBuilder中的未来是为了获取开关的当前值(我这样做是为了如果值更新失败,开关仍然是正确的值)。当我切换开关时,我调用setState来改变开关的值和数据库上的值。这样做的一个副作用是,每次使用开关时,开关和FutureBuilder都要重新构建,导致开关闪烁。

有没有办法在FutureBuilder中实现开关,让它正确地做 "开关 "动画?

这是我的开关小部件。

dynamic currentValue = false;

  Future<void> _changeValue(String optionName, dynamic value) async {
    await widget.db
        .collection('CameraSettings')
        .document(optionName)
        .updateData({optionName: value});
  }

  Future<dynamic> _getValue(String optionName) async {
    DocumentSnapshot value =
        await widget.db.collection('CameraSettings').document(optionName).get();
    return value.data[optionName];
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: _getValue(widget.optionName),
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
          currentValue = snapshot.data;
          return Switch(
            value: currentValue,
            onChanged: (bool newVal) {
              setState(
                () {
                  currentValue = newVal;
                  _changeValue(widget.optionName, newVal);
                },
              );
            },
          );
        } else {
          return Switch(value: currentValue, onChanged: null);
        }
      },
    );
  }
firebase flutter google-cloud-firestore
1个回答
1
投票

你可以在init状态下获取数据,这样当你调用setState时就不会再被调用。

创建一个变量来检查数据是否到达,现在在init状态下调用_getValue。

bool isDataloaded = false;
bool currentValue = false;

现在在初始状态下调用_getValue。

  @override
  void initState() {
    super.initState();
    _getValue(widget.optionName).then((snapshot) {
      setState(() {
        currentValue = snapshot;
        isDataloaded = true;
      });
    });
  }

现在建立widget

return Container(
    child: isDataloaded ? Switch(
        value: currentValue,
        onChanged: (bool newVal) {
          setState(
            () {
              currentValue = newVal;
              _changeValue(widget.optionName, newVal);
            },
          );
        },
      ): Switch(value: currentValue, onChanged: null)
 );
© www.soinside.com 2019 - 2024. All rights reserved.