替换 blocprovider 中的 Bloc 实例

Replacing an instance of a Bloc in a blocprovider

我正在尝试找到一种方法来创建新的 bloc 实例并将其反映在 multibloc 提供程序中。

目前我有以下内容:

Scaffold(
        appBar: AppBar(),
        body: MultiBlocProvider(
          providers: [
            BlocProvider<BlocABloc>(
              create: (BuildContext context) => _aBloc,
            ),
            BlocProvider<BlocBBloc>(
              create: (BuildContext context) => _bBloc,
            ),
          ]...

然后我尝试创建一个新的 BlocABloc 实例以及 BlocBBloc 为:

generateNew(){
setState(() {
 _aBloc = BlocABloc();
 _bBloc = BlocBBloc();
});
}

我原以为构建函数会重新执行,并且在 BlocProvider 中使用了新实例。但是,我发现 BlocBuilder 仍在从先前的 Bloc 实例获取状态。

有没有办法处理这种情况?

您遇到了与 re-execute 和创建新实例相关的问题。你需要这样使用它:

  BlocProvider.of<BlocABloc>(context);

您可以阅读more

我不知道你为什么要这样做。但是您可以使用 key 强制再次执行 BlocProvider create 方法。这是一个如何做到这一点的例子。

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutterblocrecreate/bloc_a_bloc.dart';

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

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

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  BlocA _blocA;

  @override
  void initState() {
    super.initState();
    _blocA = BlocA(1);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: MultiBlocProvider(
        providers: [
          BlocProvider<BlocA>(
            key: ValueKey(_blocA.state),
            create: (context) {
             return _blocA;
            },
          ),
        ],
        child: BlocBuilder<BlocA, int>(builder: (context, int state) {
          return Column(
            children: <Widget>[
              SizedBox(
                height: 16,
              ),
              Text("Bloc stat: $state"),
              SizedBox(
                height: 16,
              ),
              Center(
                child: RaisedButton(
                  child: Text("Create New Bloc"),
                  onPressed: _generateNew,
                ),
              )
            ],
          );
        }),
      ),
    );
  }

  _generateNew() {
    setState(() {
      _blocA.close();
      _blocA = BlocA(2);
    });
  }
}