带有和不带有 Equatable 的 Flutter bloc 导航
Posted
技术标签:
【中文标题】带有和不带有 Equatable 的 Flutter bloc 导航【英文标题】:Flutter bloc navigation with and without Equatable 【发布时间】:2021-12-14 14:40:31 【问题描述】:当bloc 状态从Equatable 扩展时,我只能将一个状态导航到另一个屏幕。否则,当状态没有从 Equatable 扩展时,我可以尽可能多地导航到另一个屏幕。
我知道状态和事件应该从 Equatable by Best Practices 扩展,以便能够运行 bloc 测试。也可以使用 Second bloc 覆盖第二个屏幕上的后退按钮行为并执行 Navigator.of(context).push(MaterialPageRoute(builder: (_) return const FirstPage();))
,但这似乎是一个错误的举动。
问题:是否可以使用 Equatable 多次导航到另一个屏幕而不覆盖第二个屏幕上的后退按钮功能?
代码:
块
// main_bloc.dart
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
// bloc
class MainBloc extends Bloc<MainEvent, MainState>
MainBloc() : super(MainInitial())
on<OpenSecondPageEvent>((event, emit)
emit(OpeningSecondPageState());
);
// States
abstract class MainState extends Equatable
const MainState();
@override
List<Object> get props => [];
class MainInitial extends MainState
class OpeningSecondPageState extends MainState
// Events
abstract class MainEvent extends Equatable
const MainEvent();
@override
List<Object> get props => [];
class OpenSecondPageEvent extends MainEvent
用户界面
// main.dart
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
void main()
runApp(const MyApp());
class MyApp extends StatelessWidget
const MyApp(Key? key) : super(key: key);
@override
Widget build(BuildContext context)
return MaterialApp(
home: BlocProvider(
create: (context) => MainBloc(),
child: BlocConsumer<MainBloc, MainState>(
listener: (context, state)
if (state is OpeningSecondPageState)
Navigator.of(context).push(MaterialPageRoute(builder: (_)
return const SecondPage(); // <- Navigating to second screen
));
,
builder: (context, state)
return Scaffold(
appBar: AppBar(
title: const Text('Page A'),
),
body: Center(
child: ElevatedButton(
child: const Text('Open Page B'),
onPressed: () =>
context.read<MainBloc>().add(OpenSecondPageEvent()),
),
),
);
,
),
),
);
class SecondPage extends StatelessWidget
const SecondPage(Key? key) : super(key: key);
@override
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(
title: const Text('Page B'),
),
body: Container(),
);
使用 Equatable
没有 Equatable
【问题讨论】:
只是好奇,为什么只为这个基本导航设置Bloc
?您的集团中没有其他业务逻辑,那么为什么不直接在onPressed
中进行导航并完成它呢?这会给你你正在寻找的行为。似乎有很多额外的代码没有任何好处。话虽如此,它只工作一次,因为Equatable
在一次推送后并不认为它是一个新状态。第一次推送是MainInitial
到OpeningSecondPageState
,这样就可以了。第二次推送已经是OpeningSecondPageState
,所以BlocBuilder
不会对它认为相同的状态做出反应。
@Loren.A 回答您的问题,您所看到的只是一个由更复杂的应用程序组成的示例。我删除了与问题无关的所有内容。至于在第二次推送中被认为相同的州,我从我的其他经验中了解到,但无论如何感谢您强调这一点。我想知道有什么方法可以让BlocBuilder
对第二次推送做出反应,或者通过Bloc
和Equatable
听到关于导航主题的其他想法。
【参考方案1】:
作为一种解决方法,可以在OpenSecondPageState()
之后立即发出MainInitial()
状态。
我不认为这是最终解决方案,但它或多或少是整洁的。
在代码中查找// <- Added part
。
更新集团:
// main_bloc.dart
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
// bloc
class MainBloc extends Bloc<MainEvent, MainState>
MainBloc() : super(MainInitial())
on<OpenSecondPageEvent>((event, emit)
emit(OpeningSecondPageState());
emit(MainInitial()); // <- Added part
);
// States
abstract class MainState extends Equatable
const MainState();
@override
List<Object> get props => [];
class MainInitial extends MainState
class OpeningSecondPageState extends MainState
// Events
abstract class MainEvent extends Equatable
const MainEvent();
@override
List<Object> get props => [];
class OpenSecondPageEvent extends MainEvent
UI部分是一样的
【讨论】:
以上是关于带有和不带有 Equatable 的 Flutter bloc 导航的主要内容,如果未能解决你的问题,请参考以下文章