我正在寻找在不同屏幕/页面上共享区块的最方便方式,而无需在材料应用程序的顶部提供。例如,我有一个Customer
块,这在CustomerListScreen
和CustomerDetailsScreen
中是必需的。区块在CustomerListScreen
中创建,并在导航时将其传递给CustomerDetailsScreen
。
Navigator.context, MaterialPageRoute(builder: (context) => CustomerDetailsScreen(context.read<CustomerBloc>())));
这就是我现在所遵循的程序。正在寻找更好的方法。。
使用BlocProvider.value.
BlocProvider可用于向小部件树的新部分提供现有区块。当现有的集团需要提供给新的路线时,这将是最常用的。在这种情况下,BlocProvider不会自动关闭区块,因为它没有创建它。
BlocProvider.value(
value: context.read<CustomerBloc>(),
child: CustomerDetailsScreen(),
);
您可以将Blob作为页面的必填字段,像这样的东西:
class CustomerDetailsScreen extends StatelessWidget {
CustomerDetailsScreen(this.mybloc);
final Bloc mybloc;
@override
Widget build(BuildContext context) {
return BlocProvider.value(
value: mybloc,
child: Text('Body...'),
);
}
}
现在,即使你使用像AutoRoute这样的软件包,你仍然可以将区块提供给页面路由。
尽管我不喜欢这个解决方案,因为如果你浏览了一个url,那么你就无法将区块传递给它,为此我建议使用嵌套导航读取此
如果你使用AutoRoute ,它会看起来像这样
@MaterialAutoRouter(
replaceInRouteName: 'Page,Route',
routes: <AutoRoute>[
AutoRoute(
page: BlocProviderPage,
children: [
AutoRoute(page: CustomerListScreen),
AutoRoute(page: CustomerDetailsScreen),
],
),
],
)
class $AppRouter {}
class BlocProviderPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => MyBloc(),
child: AutoRouter(),
);
}
}
这样,两个页面都可以访问区块,如果没有BlocProviderPage
作为它们的父级,你就无法导航到它们
将上下文名称更改为其他名称,并像下面的一样传递该上下文
@override
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider<AuthBloc>(
create: (BuildContext context) => AuthBloc(),
),
],
child: Scaffold(
appBar: AppBar(
title: const Text("Log In"),
centerTitle: true,
backgroundColor: ContactColors.primaryColor,
),
backgroundColor: ContactColors.offwhite,
body: BlocConsumer<AuthBloc, AuthState>(listener: (c, state) {
if (state is AuthError) {
print("error state");
} else if (state is AuthSuccess) {
print("success");
}
}, builder: (c, state) {
if (state is AuthLoading) {
print("loader");
return loginbox(c);
} else {
return loginbox(c);
}
// return widget here based on BlocA's state
})));
}