Flutter bloc:更新状态不会重新调用 BlocBuilder

Posted

技术标签:

【中文标题】Flutter bloc:更新状态不会重新调用 BlocBuilder【英文标题】:Flutter bloc: updating the state does not re-call BlocBuilder 【发布时间】:2019-12-28 12:15:02 【问题描述】:

我有一个使用 bloc 管理的页面

这里是home_state.dart

import 'package:banha/data/models/category.dart';
import 'package:flutter/material.dart';

abstract class HomeState 
  HomeState() : super();


class HomeInitial extends HomeState 

class UpdateCats extends HomeState 
  final List<Category> cats;
  final int rand;
  UpdateCats(@required this.cats,@required this.rand)
    print(this.cats);
    print(this.rand);
  

还有home_bloc.dart注意:随机数只是为了确保状态与前一个不同)

import 'dart:math';

import 'package:banha/data/models/category.dart';
import 'package:banha/data/network/categories.dart';
import 'package:banha/ui/tabs/home/bloc/home_events.dart';
import 'package:banha/ui/tabs/home/bloc/home_states.dart';
import 'package:bloc/bloc.dart';

class HomeBloc extends Bloc<HomeEvents, HomeState> 
  getAllCats() 
    dispatch(HomeGetCategories());
  

  HomeBloc() : super();

  @override
  HomeState get initialState => HomeInitial();

  @override
  Stream<HomeState> mapEventToState(HomeEvents event) async* 
    if (event is HomeGetCategories) 
      yield* _getCats();
    
  

  Stream<HomeState> _getCats() async* 
    print("getting cats");
    List<Category> newCats;
    await Network_getAllCategories().then((List<Category> cats) 
      newCats = cats;
    );
    yield UpdateCats(cats: newCats, rand: Random().nextInt(21312545));
  

和页面小部件:

import 'package:banha/ui/category/category.dart';
import 'package:banha/ui/tabs/home/bloc/home_bloc.dart';
import 'package:banha/ui/tabs/home/bloc/home_states.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

class ListingsWidget extends StatefulWidget 
  @override
  _ListingsWidgetState createState() => _ListingsWidgetState();


class _ListingsWidgetState extends State<ListingsWidget> 
  final HomeBloc _homeBloc = HomeBloc();

  @override
  void initState() 
    super.initState();
  

  @override
  Widget build(BuildContext context) 
    return Container(
      height: 130,
      padding: EdgeInsets.only(top: 10, bottom: 10),
      child: BlocListener(
        bloc: _homeBloc,
        listener: (context, state) 
          print(state);
        ,
        child: BlocBuilder<HomeBloc, HomeState>(
          bloc: _homeBloc,
          builder: (BuildContext context,HomeState state) 
            if(state is UpdateCats)
              print(state.cats);
            
            return ListView(
              scrollDirection: Axis.horizontal,
              children: <Widget>[
                InkWell(
                  borderRadius: BorderRadius.circular(1000),
                  onTap: () 
                    HomeBloc().getAllCats();
//                    Navigator.push(context, CupertinoPageRoute(builder: (context) => CategoryPage()));
                  ,
....

问题在于,在视图(小部件)中,BlocBuilder 仅在初始时被调用一次,但是当我尝试使用 HomeBloc().getAllCats(); 测试更改状态然后使用此代码打印新状态时:

if(state is UpdateCats)
              print(state.cats);
            

什么都没有发生(不再调用 Builder),我的代码有什么问题?

【问题讨论】:

【参考方案1】:

问题出在这里:

...
onTap: () 
...
  HomeBloc().getAllCats();
...
,
...

应该是_homeBloc.getAllCats();

【讨论】:

【参考方案2】:

我将BlocProvider 添加到根小部件(即主页)并解决了问题。

【讨论】:

我刚刚发现您在代码中做了一件奇怪的事情。 HomeBloc().getAllCats();,您使用本地块,但在调度事件时初始化一个新块。 BlocProvider 不是真正的问题,因为您使用的是本地集团。 @Tokenyet 完全正确

以上是关于Flutter bloc:更新状态不会重新调用 BlocBuilder的主要内容,如果未能解决你的问题,请参考以下文章

Flutter Application Bloc 侦听器未接收到状态更新

Flutter Bloc - Flutter Bloc 状态未更新

Flutter Bloc 状态更改未使用 get_it 更新 UI

如何保持我的bottomNavigationBar Cubit BLoc Flutter的状态?

Flutter bloc emmitInOrder 不会发出初始状态,但会发出

Flutter BLOC 状态更新但始终为空值