Показывать счетчик при использовании переключателя

#flutter #dart

Вопрос:

Я использую этот пакет для создания переключателя. Когда переключатель переключается в любом случае, появляется всплывающее диалоговое окно, и когда кто-то нажимает кнопку » ОК » во всплывающем диалоговом окне, некоторые данные сохраняются в базе данных, а затем переключатель переключается. Существует эта проблема со следующим кодом.

  1. При переключении кнопки переключателя переключатель не переключается до тех пор, пока значение не будет сохранено в БД. Это создает у пользователя иллюзию, что, возможно, переключатель не работает. Как я могу справиться с этим сценарием таким образом, чтобы пользователь видел, возможно, загрузочный счетчик, чтобы уведомить их о том, что об их запрошенных изменениях позаботились?

Вот код:

 SwitcherButton(
                  key: UniqueKey(),
                  value: isSwitchOn,
                  onColor: Colors.greenAccent,
                  offColor: Colors.grey,
                  onChange: (value) {
                    print(value);
                    AwesomeDialog(
                      context: context,
                      dialogType: DialogType.QUESTION,
                      animType: AnimType.TOPSLIDE,
                      title: isSwitchOn
                          ? 'Mark item as unavailable ?'
                          : 'Mark item as available?',
                      desc: '',
                      btnCancelOnPress: () {
                        setState(() {
                          // isSwitchOn=!value;
                          print(
                              'Value after cancel is '   isSwitchOn.toString());
                        });
                      },
                      btnOkText: "Yes",
                      btnCancelText: "No",
                      btnOkOnPress: () {
                        setState(() {
                          isSwitchOn = !isSwitchOn;
                          updateProductAvailability(isSwitchOn);
                        });
                      },
                    )..show();
                  },
                ),

 updateProductAvailability(bool isSwitchOn) async {
    await Provider.of<Products>(context, listen: false)
        .updateProductAvailability(widget.id, isSwitchOn)
        .then((value) => Scaffold.of(context).showSnackBar(
              SnackBar(
                content: isSwitchOn
                    ? Text('Product marked as available')
                    : Text('Product marked as unavailable'),
                duration: Duration(seconds: 2),
              ),
            )).catchError((Object error){
                Scaffold.of(context).showSnackBar(
              SnackBar(
                content:Text('Something went wrong. Please try again later.'),
                duration: Duration(seconds: 2),
              ),
            );
            });
  }
 

Обновленный Ответ, основанный на ответе Ника.

 _isLoading?CircularProgressIndicator():SwitcherButton(
                  key: UniqueKey(),
                  value: isSwitchOn,
                  onColor: Colors.greenAccent,
                  offColor: Colors.grey,
                  onChange: (value) {
                    value=!value;
                    AwesomeDialog(
                      context: context,
                      dialogType: DialogType.QUESTION,
                      animType: AnimType.TOPSLIDE,
                      title: isSwitchOn
                          ? 'Mark item as unavailable ?'
                          : 'Mark item as available?',
                      desc: '',
                      btnCancelOnPress: () {
                        setState(() {
                          // isSwitchOn=!value;
                          print(
                              'Value after cancel is '   isSwitchOn.toString());
                        });
                      },
                      btnOkText: "Yes",
                      btnCancelText: "No",
                      btnOkOnPress: () {
                        setState(() {
                          isSwitchOn = !isSwitchOn;
                          //print('isswitchon value is '   isSwitchOn.toString());
                         updateProductAvailability(isSwitchOn);
                        });
                      },
                    )..show();
                  },
                ),

 updateProductAvailability(bool isSwitchOn) async {
     setState((){
      _isLoading = true;
    });
    
    await Provider.of<Products>(context, listen: false)
        .updateProductAvailability(widget.id, isSwitchOn)
        .then((value) {
              
              // <---------------------------
              setState((){
                _isLoading = false;
              });

              Scaffold.of(context).showSnackBar(
              SnackBar(
                content: isSwitchOn
                    ? Text('Product marked as available')
                    : Text('Product marked as unavailable'),
                duration: Duration(seconds: 2),
              ),
            );}).catchError((Object error){

              // <---------------------------
              setState((){
                _isLoading = false;
              });

                Scaffold.of(context).showSnackBar(
              SnackBar(
                content:Text('Something went wrong. Please try again later.'),
                duration: Duration(seconds: 2),
              ),
            );
            });
  }
 

Ответ №1:

Для завершения работы над будущим требуется некоторое время.
Может помочь использование переменной isLoading для поддержания логики загрузки. Ниже приведен пример.

Определите, какая переменная загружается в классе состояний.

 bool isLoading = false;
 

Теперь используйте это в своем дереве виджетов везде, где это необходимо.

 isLoading ? AnySpinnerWidget() : ShowAlternativeWidget()
 

Отметьте его в соответствии с истиной и ложью и позвоните setState , чтобы обновить пользовательский интерфейс.

 updateProductAvailability(bool isSwitchOn) async {

    // <---------------------------
    setState((){
      isLoading = true;
    });
    
    await Provider.of<Products>(context, listen: false)
        .updateProductAvailability(widget.id, isSwitchOn)
        .then((value) {
              
              // <---------------------------
              setState((){
                isLoading = false;
              });

              Scaffold.of(context).showSnackBar(
              SnackBar(
                content: isSwitchOn
                    ? Text('Product marked as available')
                    : Text('Product marked as unavailable'),
                duration: Duration(seconds: 2),
              ),
            )}).catchError((Object error){

              // <---------------------------
              setState((){
                isLoading = false;
              });

                Scaffold.of(context).showSnackBar(
              SnackBar(
                content:Text('Something went wrong. Please try again later.'),
                duration: Duration(seconds: 2),
              ),
            );
            });
}
 

Комментарии:

1. Не могли бы вы поделиться кодом для showspinner, пожалуйста?

2. Любой виджет, который вы хотите использовать для отображения вращения. Я просто использовал это в качестве примера. Наиболее часто используется циркуляр-индикатор прогресса

3. Это прекрасно работает с одним незначительным сбоем. Когда выполняется обновление доступности продукта, спиннер просто останавливается по крайней мере на 3 секунды, а затем возобновляет вращение. Есть идеи, почему это может произойти?

4. Я не могу сказать, не взглянув на код. Это может быть другая проблема. Зависит от того, как вы это реализовали.

5. @bangbang Вы хотите остановить спиннер до того, как появится закусочная, или после того, как закусочная исчезнет ?