在Flutter中请求位置时,BLoC不会产生状态 [英] BLoC does not yield state when requesting for a location in Flutter

查看:142
本文介绍了在Flutter中请求位置时,BLoC不会产生状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用三个Flutter软件包来实现一项功能,用户可以通过该软件包进行刷新,使用BLoC逻辑检索地理坐标并将其传递回Flutter。

There's three Flutter packages I am using to implement a functionality whereby a user pulls to refresh, a geo-coordinate is retrieved using BLoC logic and passed back to Flutter.


  1. 请刷新

  2. BLoC

  3. Geolocator

  1. Pull to Refresh
  2. BLoC
  3. Geolocator

麻烦的是,我无法获得BLoC在我拉动刷新中调度呼叫时产生返回结果。

Trouble is, I cannot get the BLoC to yield the return result when I dispatch a call in pull-to-refresh.

geolocation_bloc.dart

class GeolocationBloc extends Bloc<GeolocationEvent, GeolocationState> {
  @override
  GeolocationState get initialState => GeolocationUninitialized();

  @override
  Stream<GeolocationState> mapEventToState(GeolocationEvent event) async* {
    if (event is RequestLocation) {
      yield* _mapGeolocationRequestLocation();
    }
  }

  Stream<GeolocationState> _mapGeolocationRequestLocation() async* {
    Position position;
    position = await Geolocator().getCurrentPosition();
    print("RETRIEVED LOCATION"); // I CAN REACH HERE EVERYTIME.
    if (position == null) {
      yield LocationLoaded(0, 0);
    } else {
      yield LocationLoaded(position.latitude, position.longitude);
    }
}

检索地理坐标。如果传感器已关闭/损坏,则返回(0,0)。

Retrieves a geo-coordinate. If sensor is off/broken, return (0,0) instead.

feed_pa​​ge.dart

@override
  void initState() {
    super.initState();
    _geolocationBloc.dispatch(RequestLocation());
  }

  void _onRefresh() {
    _geolocationBloc.dispatch(RequestLocation());
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Username')),
      body: BlocProviderTree(
        blocProviders: [
          BlocProvider<PostBloc>(bloc: _postBloc),
          BlocProvider<GeolocationBloc>(bloc: _geolocationBloc),
        ],
        child: BlocListenerTree(
          blocListeners: [
            BlocListener<GeolocationEvent, GeolocationState>(
              bloc: _geolocationBloc,
              listener: (BuildContext context, GeolocationState state) {
                if (state is LocationLoaded) {
                  print('LOADED'); // THIS NEVER GETS PRINTED WHEN PULLED TO REFRESH.
                  lat = state.latitude;
                  long = state.longitude;                 
                }
..

驱动程序类调度请求 Re questLocation() initState()中一次,每次调用 onRefresh()时。

The driver class dispatches a request RequestLocation() once in initState() and every time onRefresh() is called.

但是,第一次调用 RequestLocation()时,它已成功通过,即 initState(),随后使用 pull-to-refresh onRefresh()方法进行的调用似乎不会产生 LocationLoaded()状态。

However, while the first time RequestLocation() is called it is passes successfully i.e. in initState(), subsequent calls using the pull-to-refresh onRefresh() method does not seem to yield the LocationLoaded() state.

日志

Restarted application in 2,849ms.
I/flutter ( 6125): AppStarted
I/flutter ( 6125): RequestLocation
I/flutter ( 6125): RETRIEVED LOCATION
I/flutter ( 6125): Transition { currentState: GeolocationUninitialized, event: RequestLocation, nextState: LocationLoaded { latitude: 37.4219983, longitude: -122.084} }
I/flutter ( 6125): LOCATION LOADED
I/flutter ( 6125): RequestLocation
I/flutter ( 6125): RETRIEVED LOCATION

根据日志,第一个调用会同时打印已获取位置已加载位置,但在第二个已获取位置之后没有其他任何反应。

As per the log, the first call prints both RETRIEVED LOCATION and LOCATION LOADED, but nothing else occurs after the second RETRIEVED LOCATION.

如何解决此问题,以使刷新刷新将成功调用BLoC逻辑,该逻辑又返回具有适当坐标的 LocationLoaded()对象。

How can I fix this such that the pull to refresh will successfully call on the BLoC logic which in turn return a LocationLoaded() object with the appropriate coordinates.

推荐答案

我设法通过从<$ c $中删除 Equatable 继承来解决此问题c>状态和 Event BLoC类。 Equatable 实现相等性检查导致BlocListener没有短路到相应的if / else块:

I managed to solve this by removing the Equatable inheritance from my State and Event BLoC classes. Equatable implementation of equality checking resulted in the BlocListener not short-circuiting to the corresponding if/else block:

i.e. if (state is LocationLoaded)..

Equatable ,或者由于我在状态(纬度/经度)中传递了两个坐标,因此导致相等性检查失败。

There is a possibility that the equality check is stricter in Equatable or since I'm passing two coordinates in the state (Latitude/Longitude), it causes the equality check to fail.

状态类:

@immutable
abstract class GeolocationState extends Equatable { // Remove inheritance.
}

class LocationLoaded extends GeolocationState {
}

class GeolocationUninitialized extends GeolocationState {
}

这篇关于在Flutter中请求位置时,BLoC不会产生状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆