无法从“MultiBlocProvider”中提取出“提供者”列表

Unable to factor out list of `providers` from `MultiBlocProvider`

我想将来自多个来源的 BlocProviders 合并为一个 MultiBlocProvider。但是任何在 MultiBlocProvider 构造函数参数之外构造 BlocProvidersList 的尝试都会导致运行时错误,即无法找到 Provider<XYZ>

Error: Could not find the correct Provider<Foo> above this BlocListener<Foo, FooState> Widget

说我有

return MultiBlocProvider(
  providers: [
    BlocProvider(create: (context) => FooCubit()),
    BlocProvider(create: (context) => BarCubit()),
  ],
  child: child,
);

行得通。但是我想要

final concatenatedProviders = [
  BlocProvider(create: (context) => FooCubit()),
] + [
  BlocProvider(create: (context) => BarCubit()),
];
return MultiBlocProvider(
  providers: concatenatedProviders,
  child: child,
);

那是行不通的。即使它是单个(非串联的)列表,分解 providers 也不起作用。

我怎样才能找出提供者以便仍然可以找到他们?我已经为提供者尝试了几种类型注释,例如 List<BlocProvider<StateStreamableSource<Object?>>>List<BlocProvider<dynamic>> 等,但我找不到有效的解决方案。

试试这个,

final providers = <BlocProvider>[
      BlocProvider<FooCubit>(create: (_) => FooCubit()),
    ] +
    <BlocProvider>[
      BlocProvider<BarCubit>(create: (_) => BarCubit()),
    ];

完整的工作示例:

//foo_cubit.dart

import 'package:flutter_bloc/flutter_bloc.dart';

class FooCubit extends Cubit<int> {
  FooCubit() : super(0);

  void add(int x) {
    emit(state + x);
  }

  void substract(int x) {
    emit(state - x);
  }

  void multiply(int x) {
    emit(state * x);
  }

  void divide(int x) {
    emit(state ~/ x);
  }
}


//bar_cubit.dart
import 'package:flutter_bloc/flutter_bloc.dart';

class BarCubit extends Cubit<String> {
  BarCubit() : super("");

  void append(String str) {
    emit(state + str);
  }

  void reverse() {
    emit(String.fromCharCodes(state.codeUnits.reversed));
  }

  void clear() {
    emit('');
  }
}

 //main.dart
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:temp_bloc_runtime/bar_cubit.dart';
import 'package:temp_bloc_runtime/foo_cubit.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final providers = <BlocProvider>[
          BlocProvider<FooCubit>(create: (_) => FooCubit()),
        ] +
        <BlocProvider>[
          BlocProvider<BarCubit>(create: (_) => BarCubit()),
        ];

    return MultiBlocProvider(
      providers: providers,
      child: MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: const MyHomePage(title: 'Flutter Demo Home Page'),
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            BlocBuilder<FooCubit, int>(
              builder: (_, state) => Text(
                state.toString(),
              ),
            ),
            BlocBuilder<BarCubit, String>(
              builder: (_, state) => Text(
                state,
              ),
            ),
            const Expanded(child: SizedBox.shrink()),
            Row(
              children: [
                MaterialButton(
                  onPressed: () => context.read<FooCubit>().add(1),
                  child: const Text('+'),
                ),
                MaterialButton(
                  onPressed: () => context.read<FooCubit>().substract(1),
                  child: const Text('-'),
                ),
                MaterialButton(
                  onPressed: () => context.read<BarCubit>().append('A'),
                  child: const Text('+A'),
                )
              ],
            )
          ],
        ),
      ),
    );
  }
}