【问题标题】:BlocBuilder changes the state, but does not change the text on the screenBlocBuilder 改变状态,但不改变屏幕上的文本
【发布时间】:2020-12-23 10:17:53
【问题描述】:

我有以下问题: 我在 BLoC 架构上制作了一个迷你应用程序。 但我不会更改屏幕上的文字。

我也制作了类似的屏幕并且它们可以正常工作,也许我只是错过了一些东西,但我查看了官方文档,似乎一切都应该正常工作。

Flutter 版本-1.22.5

Bloc 和 Flutter Bloc 版本 - 6.1.0

谁能告诉你问题出在哪里?

这是应用程序代码:

main.dart

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

import 'bloc/hello_bloc.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: Scaffold(body: MyHomePage()),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final HelloBloc helloBloc = HelloBloc();

  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (context) => HelloBloc(),
      child: BlocBuilder<HelloBloc, HelloState>(builder: (context, state) {
        if (state is HelloPrinted) {
          return Center(
            child: Row(
              children: [
                Text("Hello"),
                TextButton(
                    onPressed: () {
                      helloBloc.add(PrintBloc());
                    },
                    child: Text("Print Bloc"))
              ],
            ),
          );
        }
        if (state is BlocPrinted) {
          return Center(
            child: Row(
              children: [
                Text("Bloc"),
                TextButton(
                    onPressed: () {
                      helloBloc.add(PrintHello());
                    },
                    child: Text("Print hello"))
              ],
            ),
          );
        } else {
          return Center(
            child: Row(
              children: [
                Text("Start print hello first"),
                TextButton(
                    onPressed: () {
                      helloBloc.add(PrintHello());
                    },
                    child: Text("Print hello"))
              ],
            ),
          );
        }
      }),
    );
  }
}

hello_bloc.dart

import 'dart:async';

import 'package:bloc/bloc.dart';
import 'package:meta/meta.dart';

part 'hello_event.dart';
part 'hello_state.dart';

class HelloBloc extends Bloc<HelloEvent, HelloState> {
  HelloBloc() : super(HelloInitial());

  @override
  void onTransition(Transition<HelloEvent, HelloState> transition) {
    print(transition);
    super.onTransition(transition);
  }

  @override
  Stream<HelloState> mapEventToState(
    HelloEvent event,
  ) async* {
    if (event is PrintHello) {
      await Future<void>.delayed(const Duration(seconds: 1));
      yield HelloPrinted();
    }
    if (event is PrintBloc) {
      await Future<void>.delayed(const Duration(seconds: 1));
      yield BlocPrinted();
    }
  }
}

hello_event.dart

part of 'hello_bloc.dart';

@immutable
abstract class HelloEvent {}

class PrintHello extends HelloEvent {}

class PrintBloc extends HelloEvent {}

hello_state.dart

part of 'hello_bloc.dart';

@immutable
abstract class HelloState {}

class HelloInitial extends HelloState {}

class HelloPrinted extends HelloState {}

class BlocPrinted extends HelloState {}

提前感谢大家的回答。

【问题讨论】:

  • 我认为问题在于,如果您在 blocBuilder 中自己提供 bloc,则必须将其传递给参数。在旧版本中它是bloc:,在新版本中你必须使用cubit:。参考:pub.dev/documentation/flutter_bloc/latest/flutter_bloc/…
  • 我加了cubit,但是还没用,谢谢回复

标签: flutter bloc


【解决方案1】:

看起来您正在创建HelloBloc 的两个实例。一个用于添加事件,另一个在 BlocProvider 中

class _MyHomePageState extends State<MyHomePage> {
  final HelloBloc helloBloc = HelloBloc();
return BlocProvider(
    create: (context) => HelloBloc(),

要解决此问题,请删除您用于保存为变量的实例(第一个)并添加您的事件使用 context.read&lt;HelloBloc&gt;().add(...)

这将调用正确的实例并更新您的 UI

【讨论】:

    【解决方案2】:

    您总是必须在两者之间发送另一个状态来更新状态。所以如果你想更新 HelloPrinted 你需要先发送像 yield InProgress() 这样的东西。

    if (event is PrintHello) {
          yield InProgress();
          await Future<void>.delayed(const Duration(seconds: 1));
          yield HelloPrinted();
    

    【讨论】:

    • 非常感谢您的回复!我试图添加状态“Inprogress”并添加 hello_bloc.dart “yield InProgress();”在延迟之前,但它仍然无法正常工作。即使我可以看到过渡:“颤振:过渡{ currentState:'HelloInitial'的实例,事件:'PrintHello'的实例,nextState:'InProgress'的实例}颤振:过渡:过渡{currentState:'InProgress'的实例,事件: 'PrintHello' 的实例,nextState:'HelloPrinted' 的实例 }"
    • 如果您将 InProgress 添加到 hello_state.dart,我看不出有什么问题。您应该调试代码或在 bloc 和 ui 文件中添加一些打印语句以查看失败的位置。您犯的最大错误是没有发送中间状态,这会阻止您更新状态。
    • 我设置了所有例外并在之前添加了“打印”。但我没有看到任何失败。更改状态后我注意到的唯一一件事是它甚至没有进入构建器,因此不会根据状态更改屏幕上的数据
    • 将您的 UI 更改为 builder: (context, state) {print("1"); if (state is HelloPrinted) { print("2"); return Center( 并将 3 和 4 添加到另一个 if 和 else 语句并遵循流程。会发生什么?
    • 打印了 1 和 4,但只是第一次。单击按钮后,在控制台中仅打印没有数字的转换
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    • 2020-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-22
    相关资源
    最近更新 更多