Как я могу сделать переключатель «анимировать» правильно, когда его свойство изменяется в FutureBuilder? - PullRequest
0 голосов
/ 30 апреля 2020

У меня есть переключатель, который изменяет значение в базе данных. Будущее в 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);
        }
      },
    );
  }

1 Ответ

1 голос
/ 30 апреля 2020

Вы можете получить данные в состоянии инициализации, поэтому они не будут вызываться снова при вызове setState.

создайте переменную, которая проверяет, получены данные или нет.

bool isDataloaded = false;
bool currentValue = false;

Теперь вызовите _getValue в состоянии инициализации.

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

Теперь создайте виджет

return Container(
    child: isDataloaded ? Switch(
        value: currentValue,
        onChanged: (bool newVal) {
          setState(
            () {
              currentValue = newVal;
              _changeValue(widget.optionName, newVal);
            },
          );
        },
      ): Switch(value: currentValue, onChanged: null)
 );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...