You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中借助Riverpod实现主窗口与子窗口状态同步方案咨询

解决Flutter多窗口(desktop_multi_window)与Riverpod共享状态的问题

核心原因

每个Flutter窗口默认会初始化独立的ProviderContainer,这导致主窗口和子窗口的Riverpod状态完全隔离,自然无法同步变更。要实现跨窗口状态共享,必须让所有窗口共用同一个Provider容器。

具体解决方案

1. 定义全局共享的ProviderContainer

在项目中创建一个全局变量保存主窗口初始化的ProviderContainer,确保所有窗口都能访问到它:

// lib/global.dart
import 'package:flutter_riverpod/flutter_riverpod.dart';

late final ProviderContainer globalStateContainer;

2. 主窗口使用全局容器启动

修改主窗口的main函数,初始化全局容器并通过UncontrolledProviderScope绑定到App:

// lib/main.dart
import 'global.dart';
import 'providers.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter/material.dart';
import 'package:desktop_multi_window/desktop_multi_window.dart';
import 'dart:convert';

void main() {
  // 初始化全局状态容器
  globalStateContainer = ProviderContainer();
  runApp(
    UncontrolledProviderScope(
      container: globalStateContainer,
      child: const MainWindowApp(),
    ),
  );
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('主窗口')),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              // 监听共享状态
              Consumer(
                builder: (context, ref, child) {
                  final count = ref.watch(counterProvider);
                  return Text('当前计数: $count', style: const TextStyle(fontSize: 20));
                },
              ),
              const SizedBox(height: 20),
              // 修改状态的按钮
              ElevatedButton(
                onPressed: () {
                  ref.read(counterProvider.notifier).increment();
                },
                child: const Text('增加计数'),
              ),
              const SizedBox(height: 20),
              // 创建子窗口按钮
              ElevatedButton(
                onPressed: () async {
                  await DesktopMultiWindow.createWindow(jsonEncode({
                    'windowTitle': '子窗口'
                  }))
                    ..setTitle('子窗口')
                    ..show();
                },
                child: const Text('打开子窗口'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

3. 子窗口绑定全局容器

为子窗口创建独立的入口文件(比如lib/child_main.dart),同样使用全局容器启动App:

// lib/child_main.dart
import 'global.dart';
import 'providers.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(
    UncontrolledProviderScope(
      container: globalStateContainer,
      child: const ChildWindowApp(),
    ),
  );
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('子窗口')),
        body: Center(
          child: Consumer(
            builder: (context, ref, child) {
              final count = ref.watch(counterProvider);
              return Text('主窗口同步计数: $count', style: const TextStyle(fontSize: 20));
            },
          ),
        ),
      ),
    );
  }
}

4. 配置子窗口入口

在pubspec.yaml中指定子窗口的入口文件,让desktop_multi_window能正确启动子窗口:

flutter:
  desktop_multi_window:
    entry_points:
      - lib/child_main.dart

5. 定义共享状态Provider

示例中使用的共享计数器Provider:

// lib/providers.dart
import 'package:flutter_riverpod/flutter_riverpod.dart';

final counterProvider = StateNotifierProvider<CounterNotifier, int>((ref) {
  return CounterNotifier();
});

class CounterNotifier extends StateNotifier<int> {
  CounterNotifier() : super(0);

  void increment() {
    state++;
  }
}

关键注意事项

  • 确保所有窗口都使用同一个ProviderContainer,禁止各自创建独立容器。
  • 由于desktop_multi_window是单进程多窗口模式,全局变量是安全且高效的状态共享方式。
  • 如果使用AsyncNotifier或其他异步状态,同样遵循此方案,无需额外修改。

内容的提问来源于stack exchange,提问作者Ben Alex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 13:43:16