示例状态:
abstract class ExampleState extends Equatable {
const ExampleState();
}
class LoadingState extends ExampleState {
//
}
class LoadedState extends ExampleState {
//
}
class FailedState extends ExampleState {
//
}
Run Code Online (Sandbox Code Playgroud)
示例_事件:
abstract class ExampleEvent extends Equatable {
//
}
class SubscribeEvent extends ExampleEvent {
//
}
class UnsubscribeEvent extends ExampleEvent {
//
}
class FetchEvent extends ExampleEvent {
//
}
Run Code Online (Sandbox Code Playgroud)
示例_块:
class ExampleBloc extends Bloc<ExampleEvent, ExampleState> {
@override
ExampleState get initialState => LoadingState();
@override
Stream<ExampleState> mapEventToState(
ExampleEvent event,
) …Run Code Online (Sandbox Code Playgroud) 我是 Bloc 架构的新手,最近看了一些教程。我有一个 StatelessWidget 页面,在里面我使用 BlocProvider 来初始化 UI 中的 Bloc。它将根据状态变化返回不同的小部件。
\n但即使在教程中,他们也仅从其他小部件调度事件(例如通过按按钮)。但在我的情况下,我需要在 Bloc Event 中的 Widget 之外调用 init API 调用。
\n如果我在其他 Widget 中,我可以调用它BlocProvider.of<FirstTabBloc>(context).dispatch(GetUserProfile());,但无法在 main() 中调用它,因为上下文不是来自 Widget。
代码:
\nclass FirstPage extends StatelessWidget {\n @override\n Widget build(BuildContext context) {\n return Scaffold(\n body: SingleChildScrollView(\n child: firstTabElement(context),\n ),\n appBar: EmptyAppBar(mainAppColor),\n );\n }\n\n BlocProvider<FirstTabBloc> firstTabElement(BuildContext context) {\n return BlocProvider(\n builder: (_) => sl<FirstTabBloc>(),\n child: Expanded(\n child: Container(\n height: MediaQuery.of(context).size.height,\n width: MediaQuery.of(context).size.width,\n child: Column(\n children: <Widget>[\n Stack(\n children: [\n //Main Background\n …Run Code Online (Sandbox Code Playgroud) 我在项目中使用go_router 。我有一个单独的文件,其中包含一个 GoRouter 实例以及所有路由(主页、登录、注册)。然后,我用肘加了认证。因此,我必须将 GoRouter 实例修改为通过 auth cubit 接收的函数,并使用它重定向到适当的路由。
一切看起来都很好,但后来我意识到了一些事情。例如,如果我在登录路径中并将寄存器推送到堆栈并修改寄存器页面并保存文件,则热重载将使我返回登录。因此,每次我想对注册页面进行一些更改时,我都会返回登录路线,然后手动返回注册页面以查看我的更改。
这是一个例子:
PS:我刚刚开始使用go_router包,所以也许我做错了什么。
我正在使用 bloc 来处理注册表单的状态。但我收到错误:
Error: Could not find the correct Provider<CreateDidBloc> above this BlocBuilder<CreateDidBloc, CreateDidState> Widget。
正如您在错误中看到的,我确实使用了块CreateDidBloc和状态CreateDidState,并通过 BlocBuilder 获取它们。
BlocBuilder 位于我的“注册”页面中,在我的例子中称为Creation。当我从介绍页面导航到创建页面时,会发生该错误。
下面是我的摘录,其中我用和MaterialApp包装了创建页面,以便创建页面可以访问 Bloc 和存储库。但由于某种原因,导航到创建页面后,页面找不到 BlocProvider 。RepositoryProviderBlocProvidercreationCreateDidBloc
initialRoute: "/introduction",
routes: {
"/introduction": (context) => Introduction(),
"/create": (context) => RepositoryProvider(
create: (context) => CreateDidRepository(),
child: BlocProvider(
create: (BuildContext context) => CreateDidBloc(
repo: context.read<CreateDidRepository>(),
),
child: Creation(),
),
),
},
Run Code Online (Sandbox Code Playgroud)
这是我导航到屏幕的方式Creation:
Navigator.push(context,
PageTransition(type: PageTransitionType.fade, child: Creation()));
Run Code Online (Sandbox Code Playgroud)
创建(注册)页面:
@override
Widget …Run Code Online (Sandbox Code Playgroud) 我在一个小应用程序中使用 Flutter 和 flutter_bloc,并且我使用 MultiBlocProvider 在主主页中使用我需要的多个 BlocProvider,并且在主页下有一个 MainWidget,它可以通过以下方式轻松访问给定的 Bloc:BlocProvider.of<OldBloc>(context)
MainWidget 调用NewWidget 作为对话框:showDialog(context: context, builder: (context) => NewWidget())
问题是,我无法从 NewWidget() 访问 OldBloc,所以我假设 MainWidget 在使用 showDialog 时没有将其上下文传递给 NewWidget ?
主屏幕.dart
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: MultiBlocProvider(
providers: [
BlocProvider(
create: (context) => OldBloc()..add(Initialize()),
),
BlocProvider(
create: (context) => OtherBloc()..add(Initialize()),
),
],
child: Stack(
children: [
MainWidget(),
MenuWidget(),
],
),
));
}
}
Run Code Online (Sandbox Code Playgroud)
MainWidget.dart
import …Run Code Online (Sandbox Code Playgroud) 我构建了一个使用 flutter_bloc 的应用程序。我想使用 go_router 进行导航。但是对于动态路由,我如何将 GoRouter refreshListener 参数与 flutter_bloc 一起使用
GoRouter(
routes: [
GoRoute(
path: '/',
name: 'home',
pageBuilder: (context, state) => HomePage.page(),
),
GoRoute(
path: '/login',
name: 'login',
pageBuilder: (context, state) => LoginPage.page(),
),
],
redirect: (state) {
final isLoggedIn =
bloc.state.status == AuthenticationStatus.authenticated;
final isLoggingIn = state.location == '/login';
if (!isLoggingIn && !isLoggingIn) return '/login';
if (isLoggedIn && isLoggingIn) return "/";
return null;
},
refreshListenable:
);
Run Code Online (Sandbox Code Playgroud) 我用 BlocProvider / BlocListener 包装了 MaterialApp
我收到一个错误
"Unhandled Exception: 'package:go_router/src/router.dart': Failed assertion: line 280 pos 12: 'inherited != null': No GoRouter found in context" from the Listener callback
Run Code Online (Sandbox Code Playgroud)
Widget build(BuildContext context) {
return BlocProvider<AuthenticationBloc>(
create: (context) => AuthenticationBloc()..add(AppStarted()),
child: BlocListener<AuthenticationBloc, AuthenticationState>(
listener: (context, state) {
if (state is AuthenticationUnauthenticated) {
context.goNamed(LoginPage.routeName);
}
if (state is AuthenticationAuthenticated) {
context.goNamed(NavigationBarContainer.routeName);
}
},
child: MaterialApp.router(
title: 'Flutter Demo',
routeInformationProvider: _router.routeInformationProvider,
routeInformationParser: _router.routeInformationParser,
routerDelegate: _router.routerDelegate,
theme: ThemeData(
primarySwatch: Colors.blue,
)),
),
);
}
Run Code Online (Sandbox Code Playgroud) 我最近在 youtube ( https://www.youtube.com/watch?v=knMvKPKBzGE&t=3s ) 上观看了 felix Angelov 的 flutter_bloc 包 ( https://pub.dev/packages/flutter_bloc ) 演讲,非常棒!
我对在 dispose 方法中手动关闭块有一些困惑。我从演讲中听说,如果我们使用 flutter_bloc 包,我们就不必调用 bloc 的 dispose 方法,如果这是错误的,请纠正我。
提前致谢
我只是在一瞬间就知道了一肘。我在教程视频中学习,因此在该视频中,导师制作了一个登录页面,其中包含电子邮件和密码文本字段以及一个登录按钮。在该视频中,导师仍然使用旧版本的 flutter_bloc。当我遵循其中一行代码时出现警告
child: ElevatedButton(
onPressed: () {
context.watch<AuthCubit>().signIn(
_emailController.text,
_passwordController.text);
}
Run Code Online (Sandbox Code Playgroud)
该代码写在 onPressed 函数按钮内。它说这context.bloc已被弃用。当我尝试运行该应用程序时,它返回一个错误,因为我使用的 flutter_bloc 版本不支持空安全,因此我将其升级到当前版本(7.3.1),我在版本 6.1.0 变更日志中找到了这一点(你可以看到它在flutter_bloc 更改日志中)
deprecated: context.bloc in favor of context.read and context.watch
Run Code Online (Sandbox Code Playgroud)
因为我不知道区别,所以我只是更改context.bloc为context.watch然后再次运行该应用程序,它返回另一个错误
Tried to listen to a value exposed with a provider, from outside of the widget tree.
This is likely caused by an event handler (like a button's onPressed) that called
Provider.of without passing `listen: false`.
To fix, write:
Provider.of<AuthCubit>(context, listen: false);
It is unsupported …Run Code Online (Sandbox Code Playgroud) 在 Flutter 上,我想将本地传递bloc到另一个屏幕。这就是我在使用默认导航器时将块传递到新路线的方式。
Navigator.of(context).push(
MaterialPageRoute<void>(
builder: (BuildContext context) => BlocProvider.value(
value: localBloc,
child: MyPage(),
),
));
Run Code Online (Sandbox Code Playgroud)
但现在,我正在使用该go_router包进行导航。我怎样才能将本地提供bloc给我想要使用的屏幕BlocProvider.value()。