我正在开发一个Ffltter应用程序,其中我有一个管理文件上传过程的ChangeNotifier服务.此服务具有Boolean isUploding属性,可跟踪当前是否正在上载文件.我试图通过更改基于isUploding的FileViewPage小部件AppBar中的图标来反映UI中的上传状态.

我的应用程序 struct 在Main函数的顶层包含一个多提供者:

void main() { // Main function is the base of the app I need the icon change in the next page not here.
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => SharedFilesProvider()),
        ChangeNotifierProvider(create: (_) => CloudService()),
      ],
      child: MyApp(), // MyApp is the root widget of your application
    ),
  );
}

在下一页(这是进入应用程序的几个导航步骤),我试图使用iscurrenting的状态在AppBar中的两个图标之间切换:

final isUpdating = context.watch<CloudService>().isUploading ?? false;

return Scaffold(
  appBar: AppBar(
    actions: <Widget>[
      IconButton(
        icon: Icon(
          isUpdating ? Icons.cloud_upload_outlined : Icons.cloud_queue_outlined,
          color: Colors.white,
        ),
        onPressed: () => {},
      ),
    ],
  ),
);

在CloudService中,在presChanges方法中isUpload状态发生变化,该方法执行异步文件上传,并相应地更新isUploding:

class CloudService extends ChangeNotifier {
  bool? _isUploading;

  bool? get isUploading => _isUploading;

  // Method to push changes, updates _isUploading and calls notifyListeners()
  Future<void> pushChanges() async {
    _isUploading = true;
    notifyListeners();
    // Simulated file upload process
    await Future.delayed(Duration(seconds: 2));
    _isUploading = false;
    notifyListeners();
  }
}

当isUpload更改时,图标不会动态更新.我希望图标在isUploading值为True时切换到Icon.Cloud_Upload_Outline,在值为False时切换回Icon.Cloud_Queue_Outline,但一旦加载页面,该图标就保持不变.

我执行了一次热重启,以确保这不是一个热重新加载问题,并且我已经通过调试确认,当isUpload更改时,可以像预期的那样调用NotifyListeners().

我想我无法将提供者与appBar连接起来. 上传时不会将False更改为True.

推荐答案

initState是当有状态小部件被插入到小部件树中时调用的方法.它对于执行依赖于窗口小部件BuildContext的初始化任务以及在窗口小部件完全初始化并准备好交互时需要执行的任何任务都是有用的.可以将其视为一种执行无法在类的构造函数中完成的任务的方法,因为它们依赖于需要访问上下文.`initState是在State类的构造函数之后调用的,因此在构造函数中初始化的任何数据都已经可用.

虽然可以在initState方法中进行初始网络调用,但通常不建议这样做,因为这意味着每次将这样的小部件插入树中时,都会执行该调用.

你的问题没有一个简单的解决办法.看起来你遇到了与state-management of your app有关的问题.我建议将网络调用移动到不依赖于您的窗口小部件树的其他地方(可能是您的"main()"函数),而是移动到应用程序的全局状态.由于您正在执行异步调用并与网络服务交互,因此不能依赖simple app state management技术.我建议:

  1. 理解difference between ephemeral state and app state
  2. 对于复杂的应用程序,状态管理为Learning about the different approaches.

对于使用哪种状态管理方法没有正确的 Select ,但由于您已经启动了提供程序和ChangeNotifier,我建议升级到Riverpod.

Flutter相关问答推荐

为什么我需要等待重新访问Firestore数据库,即使它已经做了之前?

如何在凌晨12点显示00:00(24小时格式)而不是在Flutter 中显示24:00

使用Future函数的容器中未显示图像,但在使用图像小工具时显示

Flutter :URI的目标不存在

轻松本地化包翻译在底部导航栏项目标签Flutter 翼dart 中不起作用

如何在Flutter 安全存储器中存储对象值?

如何画三角形的圆角?

Flutter中的编译时间常量方法

如何使listview.builder在筛选列表后实时更新

使用 Flutter 显示/隐藏带有下拉抽屉动画的小部件

使用 Flutter 和 Dio 将图像上传到 API

Flutter屏幕适配 - 在模拟器和真实手机上文本尺寸不同

应用程序和应用程序内的 webview 之间的单点登录

Show Snackbar above to showModalBottomSheet Flutter

在 CircleAvatar 中放置芯片

如何在 flutter 中过滤 DateTime(intl)?

Getx Flutter 在更新值时抛出空错误

Positioned 的宽度或 SizedBox 的宽度都不适用于堆栈小部件 - Flutter

Flutter 活跃的互联网连接

解密 Modulr 安全令牌