希望有人能帮我:) 我有一个flutter应用程序,并使用provider package来管理状态.

What I want to achieve: 当我点击按钮并删除订单时,我想通知我的按钮并提供isLoading值.当isLoading == true时,按钮应显示加载微调器并降低其不透明度.

What is the current state: 当我点击按钮时,订单被删除,但既不透明度降低,也不显示加载微调器.不过,我可以在我的按钮中访问isLoading.

这是我的订单服务(store):

import ...

class OrderService with ChangeNotifier {
  final supabaseClient = Supabase.instance.client;

  bool _isLoading = false;

  bool get isLoading => _isLoading;

  _toggleLoading() {
    _isLoading = !_isLoading;
    notifyListeners();
  }

  Future<void> deleteOrderWithId(int id, BuildContext context) async {
    try {
      _toggleLoading();
      await supabaseClient.from('orders').delete().eq('id', id);
    } catch (err) {
      print(err);
    } finally {
      _toggleLoading();
    }
  }

  Future<void> createOrderFromOrder(Order order, BuildContext context) async {...}
}

这是我的自定义按钮:

import ...

class TrustyButton extends StatelessWidget {
  final void Function() onTap;
  final String text;
  final ButtonType type;
  final Icon? icon;

  TrustyButton({
    super.key,
    required this.onTap,
    required this.text,
    required this.type,
    this.icon,
  });

  final Map<ButtonType, Map<String, Color>> color = {...}

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => OrderService(),
      child: Consumer<OrderService>(
        builder: (context, orderService, _) => GestureDetector(
          onTap: () {
            onTap();
          },
          child: Opacity(
            opacity: orderService.isLoading ? 0.5 : 1,
            child: Container(
              height: 56,
              decoration: BoxDecoration(
                color: color[type]!['backgroundColor']!,
                borderRadius: const BorderRadius.all(
                  Radius.circular(20),
                ),
                boxShadow: [
                  BoxShadow(
                    color: const Color(0x15000000),
                    blurRadius: 10,
                    spreadRadius: 0,
                    offset: Offset.fromDirection(2, 2),
                  ),
                ],
              ),
              child: Center(
                child: orderService.isLoading
                    ? const CircularProgressIndicator(
                        color: Colors.white,
                      )
                    : renderButtonContent(),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

推荐答案

您正面临这个问题,因为您正在TrustyButton中创建OrderService的新实例.相反,您必须举起ChangeNotifierProvider<TrustyButton>,并通过TrustyButton内的Consumer使用它. 下面是一个最小的例子:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: ChangeNotifierProvider(
            create: (context) => OrderService(),
            builder: (context, _) {
              return TrustyButton(
                onTap: () => context.read<OrderService>().deleteOrderWithId(),
              );
            },
          ),
        ),
      ),
    );
  }
}

class OrderService with ChangeNotifier {
  bool _isLoading = false;

  bool get isLoading => _isLoading;

  void _toggleLoading() {
    _isLoading = !_isLoading;
    notifyListeners();
  }

  Future<void> deleteOrderWithId() async {
    try {
      _toggleLoading();
      await Future.delayed(const Duration(seconds: 5));
    } catch (err) {
      print(err);
    } finally {
      _toggleLoading();
    }
  }
}

class TrustyButton extends StatelessWidget {
  final void Function() onTap;

  TrustyButton({
    super.key,
    required this.onTap,
  });

  @override
  Widget build(BuildContext context) {
    return Consumer<OrderService>(
        builder: (context, orderService, _) => GestureDetector(
          onTap: onTap,
          child: Opacity(
            opacity: orderService.isLoading ? 0.5 : 1,
            child: Container(
              height: 56,
              decoration: BoxDecoration(
                color: Colors.amberAccent,
                borderRadius: const BorderRadius.all(
                  Radius.circular(20),
                ),
                boxShadow: [
                  BoxShadow(
                    color: const Color(0x15000000),
                    blurRadius: 10,
                    spreadRadius: 0,
                    offset: Offset.fromDirection(2, 2),
                  ),
                ],
              ),
              child: Center(
                child: orderService.isLoading
                    ? const CircularProgressIndicator(
                        color: Colors.white,
                      )
                    : Text('Delete'),
              ),
            ),
          ),
        ),
      );
  }
}

Flutter相关问答推荐

无法在Flatter中设计正确的布局

Riverpod生成器和生成util类

在fltter_widget_from_html中启动url

如何实现Flutter 梳理机图像的小量移动

从.gitignore中排除.fvm/fvm_config.json

在Dart中使用Riverpod代码生成时出现问题(addListener)

Riverpod 2.0-如何使用FutureOr和AutoDisposeSyncNotificationer处理api状态代码?

从future 列表到流列表Flutter Firebase

如何将小部件代码移动到另一个文件以获得更好的可读性

如何使用 Material3 创建带有高度的完美白色提升按钮?

无法应用插件com.chaquo.python

像图像一样Flutter 自定义标签

flutter 中 // 和 /// 有什么区别

我在弹出框中编辑后无法保存日期

如何在 flutter 的alert 对话框中实现进度指示器?

如何在Flutter中制作带有波浪边框的圆圈来显示图像?

为什么 Flutter riverpod 直接分配不起作用但方法可以

Flutter NavigationBar 忽略我的背景 colored颜色

如何从用户 Flutter 导航抽屉中隐藏管理菜单

Flutter 广告导致延迟