【问题标题】:How can I have this Flutter Bloc to send updates?我怎样才能让这个 Flutter Bloc 发送更新?
【发布时间】:2020-09-13 06:22:13
【问题描述】:

我有这个 Flutter 块,它采用 Firebase 餐厅流,根据相对于用户的位置,将根据餐厅位置仅过滤最近的餐厅。它工作正常,但如果我想查看餐厅文件中的任何更改,我必须使用 RefreshIndicator 刷新。我错过了什么?提前致谢。

class NearestRestaurant {
  final String id;
  final Restaurant restaurant;
  final double distance;

  NearestRestaurant({this.id, this.restaurant, this.distance});
}

class NearRestaurantBloc {
  final Future<List<Restaurant>> source;
  final Position userCoordinates;
  final _stream = StreamController<List<Restaurant>>();

  NearRestaurantBloc({
    this.source,
    this.userCoordinates,
  }) {
    List<Restaurant> resList = List<Restaurant>();
    source.then((rest) {
      rest.forEach((res) async {
        await Geolocator().distanceBetween(
          userCoordinates.latitude,
          userCoordinates.longitude,
          res.coordinates.latitude,
          res.coordinates.longitude,
        ).then((distance) {
          if (res.active && distance < res.deliveryRadius) {
            resList.add(res);
          }
        });
        _stream.add(resList);
      });
    });
  }

  Stream<List<Restaurant>> get stream => _stream.stream;

  void dispose() {
    _stream.close();
  }
}


class RestaurantQuery extends StatefulWidget {

  @override
  _RestaurantQueryState createState() => _RestaurantQueryState();
}

class _RestaurantQueryState extends State<RestaurantQuery> {
  NearRestaurantBloc bloc;

  @override
  Widget build(BuildContext context) {
    final database = Provider.of<Database>(context, listen: true);
    final session = Provider.of<Session>(context);
    final userCoordinates = session.position;
    bloc = NearRestaurantBloc(
        source: database.patronRestaurants(),
        userCoordinates: userCoordinates,
    );
    return StreamBuilder<List<Restaurant>>(
      stream: bloc.stream,
      builder: (context, snapshot) {
        bool stillLoading = true;
        var restaurantList = List<Restaurant>();
        if (snapshot.connectionState == ConnectionState.active) {
          if (snapshot.hasData && snapshot.data.length > 0) {
            restaurantList = snapshot.data;
          }
          stillLoading = false;
        }
        return Scaffold(
          appBar: AppBar(
            title: Text(
              'Restaurants near you',
              style: TextStyle(color: Theme.of(context).appBarTheme.color),
            ),
            elevation: 2.0,
          ),
          backgroundColor: Theme.of(context).scaffoldBackgroundColor,
          body: RefreshIndicator(
            onRefresh: () async {
              setState(() {

              });
            },
            child: RestaurantList(
              nearbyRestaurantsList: restaurantList,
              stillLoading: stillLoading,
            ),
          ),
        );
      },
    );
  }

  @override
  void dispose() {
    bloc.dispose();
    super.dispose();
  }

}

【问题讨论】:

    标签: firebase flutter bloc


    【解决方案1】:

    _RestaurantQueryState 下的build 方法中,您将在builder 方法之外返回scaffold。最初,restaurantList 为空。因此,您不会生成列表。每当流更新时,您都会获取快照数据以更新restaurantList

    问题出现在这里。即使restaurantList 已更新,小部件RestaurantList 也不会更新,因为它位于构建器方法之外。您可以使用以下代码。在这里,我们创建一个包含 RestaurantList 小部件的小部件。每当流更新时,小部件就会更新。

    class _RestaurantQueryState extends State<RestaurantQuery> {
      NearRestaurantBloc bloc;
    
      @override
      Widget build(BuildContext context) {
        final database = Provider.of<Database>(context, listen: true);
        final session = Provider.of<Session>(context);
        final userCoordinates = session.position;
    
        //////////////////////////////////
        //initialize RestaurantList widget
        //////////////////////////////////
        Widget restaurantWidget = RestaurantList(
                  nearbyRestaurantsList: [],
                  stillLoading: false,
                );
    
    
        bloc = NearRestaurantBloc(
            source: database.patronRestaurants(),
            userCoordinates: userCoordinates,
        );
        return StreamBuilder<List<Restaurant>>(
          stream: bloc.stream,
          builder: (context, snapshot) {
            bool stillLoading = true;
            var restaurantList = List<Restaurant>();
            if (snapshot.connectionState == ConnectionState.active) {
              if (snapshot.hasData && snapshot.data.length > 0) {
                restaurantList = snapshot.data;
                /////////////////////////////
                //update the restaurant widget
                //////////////////////////////
                restaurantWidget = RestaurantList(
                  nearbyRestaurantsList: restaurantList,
                  stillLoading: stillLoading,
                );
              }
              stillLoading = false;
            }
            return Scaffold(
              appBar: AppBar(
                title: Text(
                  'Restaurants near you',
                  style: TextStyle(color: Theme.of(context).appBarTheme.color),
                ),
                elevation: 2.0,
              ),
              backgroundColor: Theme.of(context).scaffoldBackgroundColor,
              ///////////////////////////
              //use the restaurant Widget
              ///////////////////////////
              body: restaurantWidget,
              ),
            );
          },
        );
      }
    

    【讨论】:

    • 谢谢,Mohammed,但它没有用。餐厅更新仍未发布。
    【解决方案2】:

    我的错。我听的是未来而不是流。这是更新后的区块代码:

    class NearestRestaurant {
      final String id;
      final Restaurant restaurant;
      final double distance;
    
      NearestRestaurant({this.id, this.restaurant, this.distance});
    }
    
    class NearRestaurantBloc {
      final Stream<List<Restaurant>> source;
      final Position userCoordinates;
      final _stream = StreamController<List<Restaurant>>();
    
      NearRestaurantBloc({
        this.source,
        this.userCoordinates,
      }) {
        List<Restaurant> resList = List<Restaurant>();
        source.forEach((rest) {
          resList.clear();
          rest.forEach((res) async {
            await Geolocator().distanceBetween(
              userCoordinates.latitude,
              userCoordinates.longitude,
              res.coordinates.latitude,
              res.coordinates.longitude,
            ).then((distance) {
              if (res.active && distance < res.deliveryRadius) {
                resList.add(res);
              }
            });
            _stream.add(resList);
          });
        });
      }
    
      Stream<List<Restaurant>> get stream => _stream.stream;
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-14
      • 2019-11-08
      • 2021-07-09
      • 2021-07-16
      • 1970-01-01
      • 2019-06-13
      • 2014-08-11
      • 1970-01-01
      相关资源
      最近更新 更多