首页
学习
活动
专区
圈层
工具
发布

Flutter BLoC: build()方法中的Navigator.pop in StreamBuilder

基础概念

Flutter BLoC: BLoC(Business Logic Component)是一种设计模式,用于将应用程序的业务逻辑与UI分离。它通过流(Stream)来管理状态,使得状态管理更加清晰和可预测。

StreamBuilder: 是一个Flutter widget,用于监听流(Stream)并在流发出新数据时重建其子树。

Navigator.pop: 是Flutter中的一个方法,用于从导航堆栈中弹出当前页面并返回到上一个页面。

相关优势

  1. 分离关注点: BLoC模式将业务逻辑与UI分离,使得代码更加模块化和易于维护。
  2. 可预测的状态管理: 通过流来管理状态,可以更容易地跟踪和调试状态变化。
  3. 响应式编程: StreamBuilder使得UI能够自动响应流中的数据变化,无需手动更新。

类型与应用场景

  • 类型: BLoC可以分为事件驱动型和状态驱动型。事件驱动型BLoC通过事件来触发状态变化,而状态驱动型BLoC则直接通过状态变化来触发UI更新。
  • 应用场景: 适用于复杂的应用程序,特别是那些需要频繁更新状态和响应用户交互的应用。

遇到的问题及解决方法

问题描述

build()方法中使用Navigator.pop可能会导致一些问题,例如:

  • 页面无法正确弹出。
  • 状态更新不及时,导致UI显示不一致。

原因分析

  1. 生命周期问题: build()方法可能会被频繁调用,如果在其中直接调用Navigator.pop,可能会导致页面弹出不稳定。
  2. 状态同步问题: 如果在build()方法中直接操作状态,可能会导致状态更新不及时,影响UI显示。

解决方法

  1. 使用事件处理器: 将Navigator.pop的调用放在事件处理器中,而不是直接在build()方法中调用。
代码语言:txt
复制
class MyBloc extends Bloc<MyEvent, MyState> {
  MyBloc() : super(InitialState());

  @override
  Stream<MyState> mapEventToState(MyEvent event) async* {
    if (event is PopEvent) {
      yield* _mapPopEventToState();
    }
  }

  Stream<MyState> _mapPopEventToState() async* {
    // 处理弹出逻辑
    Navigator.pop(context);
    yield PopState();
  }
}
  1. 使用BlocListener: 在UI层使用BlocListener来监听状态变化,并在状态变化时调用Navigator.pop
代码语言:txt
复制
BlocListener<MyBloc, MyState>(
  listener: (context, state) {
    if (state is PopState) {
      Navigator.pop(context);
    }
  },
  child: BlocBuilder<MyBloc, MyState>(
    builder: (context, state) {
      // 构建UI
    },
  ),
);

示例代码

以下是一个完整的示例,展示了如何在BLoC模式下使用StreamBuilderNavigator.pop

代码语言:txt
复制
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: BlocProvider(
        create: (context) => MyBloc(),
        child: MyHomePage(),
      ),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('BLoC Example')),
      body: Center(
        child: BlocBuilder<MyBloc, MyState>(
          builder: (context, state) {
            if (state is InitialState) {
              return ElevatedButton(
                onPressed: () {
                  context.read<MyBloc>().add(PopEvent());
                },
                child: Text('Pop Page'),
              );
            }
            return Container();
          },
        ),
      ),
    );
  }
}

abstract class MyEvent {}

class PopEvent extends MyEvent {}

abstract class MyState {}

class InitialState extends MyState {}

class PopState extends MyState {}

class MyBloc extends Bloc<MyEvent, MyState> {
  MyBloc() : super(InitialState());

  @override
  Stream<MyState> mapEventToState(MyEvent event) async* {
    if (event is PopEvent) {
      yield* _mapPopEventToState();
    }
  }

  Stream<MyState> _mapPopEventToState() async* {
    Navigator.pop(context);
    yield PopState();
  }
}

通过这种方式,可以确保Navigator.pop的调用更加稳定和可靠,同时保持代码的清晰和可维护性。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

FlutterDojo设计之道—状态管理之路(三)

通过Dart提供的Stream机制,Flutter可以很轻松的构建响应式的编程方式,同时也让跨页面、跨Widget的数据管理问题迎刃而解。 Flutter的响应式编程,具有下面几个特点。...私有的model和StreamController 公开的get方法返回Stream 公开的业务处理函数 dispose函数 创建BLoC管理类 BLoC管理类是一个通用的处理类,借助StatefulWidget...在UI层中,需要做的就是通过StreamBuilder来解析要监听的数据,StreamBuilder的builder函数是一个AsyncWidgetBuilder,它能够异步构建widget,其参数AsyncSnapshot...BLoC流的单播与广播 Flutter中的Stream分为两种,单播与多播,默认情况下创建的是单播Stream,这样的话,只能有一个StreamBuilder来监听,如果存在多个StreamBuilder...举个例子,比如在第一个界面在流中添加了一些数据,再打开第二个界面的时候,创建StreamBuilder之后,是无法直接获取流的最新数据的,因为这时候流中的的数据在StreamBuilder监听之前就已经结束了

1.8K30

Flutter ——状态管理 | StreamBuild

构造器 child: StreamBuilder( // 监听Stream,每次值改变的时候,更新Text中的内容 stream: _streamController.stream...这是我司的一张UI。 [UI.png] 要求点击“关注”变为“已关注” 如何去实现的?实现的方法有好多种。...2.方法二使用状态管理bloc,如果使用了bloc,streamBuild中的stream 就因该传bloc的数据,如果我其它地方使用也使用了这个item,那么这个stream就应该传...bloc,此时streamBuild中的stream 类型就不匹配了,这个item 就无法复用了,所以我放弃使用bloc等状态管理 3.为何item 最外层使用StatefulWidget...bloc+streamBuild,此时的stream是bloc里的,不需要在dispose()方法中去关流,这样就可以放弃使用StatefulWidget了。

3.4K31
  • Flutter BLoC 异步通信、BlocBuilder的基本使用、BlocProvider的初探

    的使用详情 | StreamBuilder组件的结合使用 | StreamBuilder 实现的倒计时进度圆圈 EventBus (不考虑使用) Bloc BLoC 异步通信、BlocBuilder...在Flutter项目开发中,一般的项目中,会有网络请求的代码与Widget构建的UI界面写一起,随着业务的不断积累,代码量也越来越大,维护的复杂度也会随着增加。...、事件、消费组合在一起,在本文章 第四小节有详细概述,代码如下: ///flutter应用程序中的入口函数 void main() => runApp(BlocMainApp()); ///应用的根布局...定义的 Bloc 角色,代码如下: import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:intl/intl.dart'; /...可以通过BlocProvider.of (context)向其子级提供bloc,如上述的 add 方法发送事件 BlocProvider.of(context).add

    3.7K11

    Flutter完整开发实战详解(十二、全面深入理解状态管理设计)

    在所有 响应式编程 中,状态管理一直老生常谈的话题,而在 Flutter 中,目前主流的有 scope_model 、BloC 设计模式 、flutter_redux 、fish_redux 等四种设计...首先我们知道 context 只是接口,而在 Flutter 中 context 的实现是 Element ,在 Element 的 inheritFromWidgetOfExactType 方法实现里...二、BloC BloC 全称 Business Logic Component ,它属于一种设计模式,在 Flutter 中它主要是通过 Stream 与 SteamBuilder 来实现设计的,所以...BloC 实现起来也相对简单,关于 Stream 与 SteamBuilder 的实现原理可以查看前篇,这里主要展示如何完成一个简单的 BloC 。...利用 StreamBuilder 加载监听 Stream 数据流,通过 snapShot 中的 data 更新控件。

    2.5K20

    flutter中使用BloC模式

    更具我自己的一点理解来看,实际上BloC设计模式,似乎和MVP没有什么本质区别,两种设计模式的最终目的就是为了把和UI糅合在一起的业务逻辑代码剥离开来,单独的抽取到一层中。...在flutter中,实现BloC模式的精髓就是, 展示的数据从BloC中来,具体到了stream上,有了stream的到来,就可以使用StreamBuilder来构建ui了。...3、便面了setState的方式来触发build,可能性能更好,注意,只是可能,因为这也是大佬们说的,我并不太认可,实际上我认为,即便是使用streamBuilder,当stream有新的data时,也是触发了其包裹的组件走...build的。...Redux相比大家也听过了,flutter中当然也是有的,那么,和Bloc有什么区别么?

    17.8K82

    优雅的UI与Model绑定 Flutter DataBus使用~

    Flutter开发中,大家都绕不开Widget的刷新,setState()是最简单的用法。...但随着当app的交互变得复杂,setState出现的次数便会显著增加,每次setState都会重新调用build方法,这势必对于性能以及代码的可阅读性带来一定的影响。...如何优雅的解决这个问题,不得不提到StreamBuilder,StreamBuilder是Flutter中异步构建的核心组件。许多著名的开源框架例如Bloc皆是基于此实现。...其实Flutter中还提供了一个强大组件SteamBuilder来协助我们处理控件的刷新构建。 ---- StreamBuilder ? ?...而且由于MultDataLine是mixin定义,所以我们可以在任意的类中混入使用方法。例如直接在Widget中混入改类,调用getLine方法获取到StreamBuilder。

    2.8K41

    【源码篇】Flutter Bloc背后的思想,一篇纠结的文章

    Bloc框架做了一些让我非常疑惑的操作,_startListening方法中的回调中调用了 e.markNeedsNotifyDependents() ,完全没用!...使用 这边介绍下使用,对官方的用法做了一些调整 调整心路的历程,可参照:flutter_bloc使用解析---骚年,你还在手搭bloc吗!...我们在 BlocProvider中传入的XxxBloc对象,赋值给了_BlocBuilderBaseState中的 _bloc变量 BlocBuilderBase抽象了一个build方法,在 _BlocBuilderBaseState...类中,实例了Stream流对象,来做Event的事件触发机制 添加Event事件时,会触发 _bindEventsToStates() 方法中的listener回调 _bindEventsToStates...] 相关地址 文章中Demo的Github地址:flutter_use Web效果:https://cnad666.github.io/flutter_use/web/index.html 如果相关功能按钮没看到

    2.6K41

    【-Flutteru002FDart 语法补遗-】 sync* 和 async* 、yield 和yield* 、async 和 await

    它标注在函数{ 之前,其方法必须返回一个 Iterable对象 的码为\u{1f47f}。...记住一点yield*后面的表达式是一个Iterable对象 比如下面getEmoji方法是核心,现在想要打印每次的时间,使用getEmojiWithTime yield*之后的getEmoji(count...-StreamBuilder Stream在组件层面最常用的就数StreamBuilder,本文只是简单用一下,以后会有专文 StreamBuilder组件使用的核心就是,它接受一个Stream对象,...1)); //模拟耗时 return String.fromCharCodes(first.map((e) => e + count)); } } ---- 题外话: 如果你使用过flutter_bloc...另外本人有一个Flutter微信交流群,欢迎小伙伴加入,共同分享Flutter的知识,期待与你的交流与切磋。

    82510

    【-FlutterDart 语法补遗-】 sync* 和 async* 、yield 和yield* 、async 和 await

    它标注在函数{ 之前,其方法必须返回一个 Iterable对象 ? 的码为\u{1f47f}。...记住一点yield*后面的表达式是一个Iterable对象 比如下面getEmoji方法是核心,现在想要打印每次的时间,使用getEmojiWithTime yield*之后的getEmoji(...-- 2020-05-20T07:35:27.511723 ---- 四、Stream的使用-StreamBuilder Stream在组件层面最常用的就数StreamBuilder,本文只是简单用一下...,以后会有专文 StreamBuilder组件使用的核心就是,它接受一个Stream对象, 根据builder函数在流元素的不同状态下构建不同的界面。...//模拟耗时 return String.fromCharCodes(first.map((e) => e + count)); } } 复制代码 ---- 题外话: 如果你使用过flutter_bloc

    5.5K40

    Flutter 入门指北(Part 13)之网络

    以上代码查看 http_main.dart 文件 实践一下下 不知道小伙还记得前面讲的 BLoC 没有,忘了可以查看 Flutter 状态管理及 BLoC,这里结合 BLoC 和 Dio 实现界面和逻辑分离的小例子...); return Scaffold( // StreamBuilder 接受更新数据的 stream body: StreamBuilder( builder: (_, AsyncSnapshot...最后代码的地址还是要的: 文章中涉及的代码:demos(https://github.com/kukyxs/flutter_arts_demos_app) 基于郭神 cool weather 接口的一个项目...,实现 BLoC 模式,实现状态管理:flutter_weather(https://github.com/kukyxs/flutter_weather) 一个课程(当时买了想看下代码规范的,代码更新会比较慢...,虽然是跟着课上的一些写代码,但是还是做了自己的修改,很多地方看着不舒服,然后就改成自己的实现方式了):flutter_shop(https://github.com/kukyxs/flutter_shop

    1.6K20

    flutter_bloc使用解析---骚年,你还在手搭bloc吗!

    flutter_bloc使用将从下图的三个维度说明 [flutter_bloc] 前言 首先,有很多的文章在说flutter bloc模式的应用,但是百分之八九十的文章都是在说,使用StreamController...+StreamBuilder搭建bloc,提升性能的会加上InheritedWidget,这些文章看了很多,真正写使用bloc作者开发的flutter_bloc却少之又少。...fish_redux的clone方法 ///也是对官方Flutter Login Tutorial这个demo中copyWith方法的一个优化 ///Flutter Login Tutorial...方法直接被移除了,一运行项目,bloc内部也会给出报错,需要你手动去注册处理器 有一说一,虽然是破坏式的改变写法,但是新写法是非常的优雅,彻底改变了以前的mapEventToState方法中的各种判断Event...} view 这地方我们需要创建使用BlocProvider一个SpanTwoCubit,这是使用Bloc的常规流程 在自增的点击事件里,我们调用本模块和SpanOneCubit中的自增方法,OK,这里我们就能同步的改变

    6K41

    Flutter完整开发实战详解(十五、全面理解State与Provider)

    这就涉及 Flutter 中 Widget 的实现原理,在之前的篇章我们介绍过,这里我们说两个涉及的概念: Flutter 中的 Widget 在一般情况下,是需要通过 Element 转化为 RenderObject...中,这样 Element 每次调用 Widget build() 时,是通过 state.build(this); 得到的新 Widget ,所以写在 State 的数据就得以复用了。...问题就在于前面 StatefulElement 的构建方法和 update 方法: State 只在 StatefulElement 的构建方法中创建,当我们调用 setState 触发 update...build 方法中使用 InheritedProvider 进行嵌套,实现 value 的共享。...,相信用过 BLoC 模式的同学会感觉很贴心,以前正常用做 BLoC 时,每个 StreamBuilder 的 snapShot 只支持一种类型,多个时要不就是多个状态合并到一个实体,要不就需要多个StreamBuilder

    3.9K21

    Flutter框架开发应用入门实践

    Flutter作为谷歌推出的新一代跨平台移动应用开发框架,凭借其高效、灵活和强大的功能,迅速在开发者社区中崭露头角。...运行和调试 在IDE中运行项目,选择模拟器或真机进行调试。Flutter的热重载功能使得开发者可以快速看到代码更改的效果。 5....开发者可以通过组合这些Widgets来创建复杂的UI界面。 2. State Management 状态管理是Flutter应用开发中的一个重要环节。...Flutter提供了多种状态管理方案,包括Provider、Riverpod、Bloc等。开发者可以根据项目需求选择合适的状态管理方案。 3. Navigation 导航是移动应用中的一个基本功能。...Flutter提供了Navigator组件,用于管理应用中的页面导航。开发者可以通过Navigator.push和Navigator.pop方法实现页面的跳转和返回。 4.

    40120
    领券