Flutter BloC 不刷新我的视图(计数器应用程序)

Nao*_*fix 1 dart flutter bloc

我正在尝试使用计数器测试应用程序使用 BloC 库,但是当我使用对象来增加/减少我的计数器时,我的视图有一个小问题。MyObject.MyProperty 增加或减少但我的视图没有刷新。为什么?

带有简单 int 变量的示例应用程序

我的对象代码:

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

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

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: BlocProvider(
        builder: (context) => CounterBloc(),
        child: CounterPage(),
      ),
    );
  }
}

class TestTest{
  int myProperty; 

  TestTest(){
    myProperty = 0;
  }
}


class CounterPage extends StatefulWidget {
  @override
  _CounterPageState createState() => _CounterPageState();
}

class _CounterPageState extends State<CounterPage> {
  @override
  Widget build(BuildContext context) {
    final counterBloc = BlocProvider.of<CounterBloc>(context);

    return Scaffold(
      appBar: AppBar(title: Text('Counter')),
      body: BlocBuilder<CounterBloc, TestTest>(
        builder: (context, myClassTestTest) { 
          return Center(
            child: Text(
              '${myClassTestTest.myProperty}',
              style: TextStyle(fontSize: 24.0),
            ),
          );
        },
      ),
      floatingActionButton: Column(
        crossAxisAlignment: CrossAxisAlignment.end,
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[
          Padding(
            padding: EdgeInsets.symmetric(vertical: 5.0),
            child: FloatingActionButton(
              child: Icon(Icons.add),
              onPressed: () {
                counterBloc.dispatch(CounterEvent.increment);
              },
            ),
          ),
          Padding(
            padding: EdgeInsets.symmetric(vertical: 5.0),
            child: FloatingActionButton(
              child: Icon(Icons.remove),
              onPressed: () {
                counterBloc.dispatch(CounterEvent.decrement);
              },
            ),
          ),
        ],
      ),
    );
  }
}


enum CounterEvent { increment, decrement }

class CounterBloc extends Bloc<CounterEvent, TestTest> {
  @override
  TestTest get initialState => TestTest();

  @override
  Stream<TestTest> mapEventToState(CounterEvent event) async* {
    switch (event) {
      case CounterEvent.decrement:        
        currentState.myProperty -= 1;
        yield currentState; 
        break;
      case CounterEvent.increment:
        currentState.myProperty += 1;
        yield currentState; 
        break;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

如您所见,我对示例应用程序进行了一些编辑,只是为了添加TestTest具有 int 属性的类myProperty。当我点击我的按钮时,我的对象中的值会发生变化,但我的视图没有刷新。

我该如何解决?

我找到了一个解决方案来重新创建我的 TestTest ,mapEventToState但是重新创建整个对象只是为了更新一个属性很奇怪......

谢谢

dev*_*jay 8

只是为未来的访问者发布另一个可能的解决方案。

如果你yield为同一个状态做两次。您的用户界面不会更新。

例如,如果您已经ShowDataToUser(data)从您的 Bloc触发,现在在另一个操作之后您ShowDataToUser(data)再次让步,您的 UI 将不会更新。

一个快速解决这个问题的方法是DummyState()在你的 Bloc 中创建一个并在DummyState()每次让步之前让步ShowDataToUser(data)

除了快速破解之外的另一个解决方案是为 dart 定义一种方法来比较和等同于一个类,cos 目前默认ShowDataToUser是同一个类,但它contents是不同的,但 Dart 不知道如何评估内容并比较它们.

进入 Equatable

为此,您需要使用包:https : //pub.dev/packages/equatable

现在您必须使用 Equtable 扩展您的 Bloc 状态,例如:

class DummyState extends Equatable {}
Run Code Online (Sandbox Code Playgroud)

现在,如果您的 Bloc States 正在扩展 Equatable,那么您必须覆盖该函数:

@override
  List<Object> get props => [name];
Run Code Online (Sandbox Code Playgroud)

name是比较两个相同类时要比较的属性/字段名称。

这个函数告诉你的 Bloc,如何区分两个相同的状态(它们可能有不同的值)。