问题描述
我是Bloc架构的新手,最近我看了一些教程。我有一个页面是StatelessWidget,在里面,我正在使用BlocProvider初始化UI中的Bloc。它将根据状态变化返回不同的小部件。
但是,即使在教程中,他们也仅从其他Widget调度事件(例如,通过按Button)。但是在我的情况下,我需要在Bloc事件中的Widget外部调用init API调用。
如果我在其他小部件中,则可以调用BlocProvider.of<FirstTabBloc>(context).dispatch(GetUserProfile());
,但是由于上下文不是来自小部件,所以不能在main()中调用它。
代码:
class FirstPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: firstTabElement(context),),appBar: EmptyAppBar(mainAppColor),);
}
BlocProvider<FirstTabBloc> firstTabElement(BuildContext context) {
return BlocProvider(
builder: (_) => sl<FirstTabBloc>(),child: Expanded(
child: Container(
height: MediaQuery.of(context).size.height,width: MediaQuery.of(context).size.width,child: Column(
children: <Widget>[
Stack(
children: [
//Main Background
Column(children: <Widget>[
//Top part
Container(
constraints: BoxConstraints(
minHeight: 120,height: 300,decoration: new Boxdecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,end: Alignment.bottomCenter,colors: ticketGradient,// Bottom part - white
Container(
color: basicWhite,]),//content above background
BlocBuilder<FirstTabBloc,FirstTabState>(
builder: (context,state) {
if (state is Uninitialized) {
return WalletWidget(
credit: formatPrice(0),currency: '€',);
} else if (state is Loading) {
return LoadingWidget();
} else if (state is Loaded) {
Wallet currWallet = state.profile.getWalletByClient(clientId);
return WalletWidget(
credit: formatPrice(currWallet.value),currency: formatCurrency(currWallet.currency),);
} else if (state is Error) {
return Messagedisplay(
message: state.message,);
}
},],)));
}
}
解决方法
您需要使用另一种方式来获得集团。
BlocProvider.of(context)
在后台使用Provider
。 Provider是一个颤振包,其中包装了InheritedWidget
。 InheritedWidget是颤动的小部件,可通过上下文将数据沿小部件树向下传递。
所以您需要另一种方式。例如,您可以使用get_it库。这是Service Locator
的出色实现。
一个简单的示例,其中的小部件位于外部
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
final bloc = CounterBloc();
void main() {
bloc.add(CounterEvent.increment);
bloc.add(CounterEvent.increment);
bloc.add(CounterEvent.increment);
bloc.add(CounterEvent.increment);
runApp(
MyApp(),);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',theme: ThemeData(
primarySwatch: Colors.blue,),home: Scaffold(
body: SafeArea(
child: MyHomePage(),);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (_) => bloc,child: CounterPage(),);
}
}
class CounterPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Counter')),body: BlocBuilder<CounterBloc,int>(
builder: (_,count) {
return Center(
child: Text('$count',style: Theme.of(context).textTheme.headline1),);
},floatingActionButton: Column(
crossAxisAlignment: CrossAxisAlignment.end,mainAxisAlignment: MainAxisAlignment.end,children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(vertical: 5.0),child: FloatingActionButton(
child: const Icon(Icons.add),onPressed: () =>
context.bloc<CounterBloc>().add(CounterEvent.increment),Padding(
padding: const EdgeInsets.symmetric(vertical: 5.0),child: FloatingActionButton(
child: const Icon(Icons.remove),onPressed: () =>
context.bloc<CounterBloc>().add(CounterEvent.decrement),],);
}
}
enum CounterEvent { increment,decrement }
class CounterBloc extends Bloc<CounterEvent,int> {
CounterBloc() : super(0);
@override
Stream<int> mapEventToState(CounterEvent event) async* {
switch (event) {
case CounterEvent.decrement:
yield state - 1;
break;
case CounterEvent.increment:
yield state + 1;
break;
default:
addError(Exception('unsupported event'));
}
}
}
在get_it中注册您的集团。然后,您可以在没有上下文的情况下使用它。
,我想你需要知道 dispatch renamed to add
> There were core api changes introduced into 1.0.0:
bloc.state.listen -> bloc.listen
bloc.currentState -> bloc.state
bloc.dispatch -> bloc.add
bloc.dispose -> bloc.close
查看 https://link.medium.com/qnfMcEcW00 了解更多详情。 希望能帮到你?