在 Flutter 中请求位置时,BLoC 不会产生状态

Car*_*ein 4 dart flutter

我使用三个 Flutter 包来实现一个功能,用户可以通过拉动刷新,使用 BLoC 逻辑检索地理坐标并将其传递回 Flutter。

  1. 拉动刷新
  2. 集团
  3. 地理定位器

问题是,当我在pull-to-refresh 中发送调用时,我无法让 BLoC 产生返回结果。

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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;                 
                }
..
Run Code Online (Sandbox Code Playgroud)

该驱动程序类调度请求RequestLocation()一次initState(),每次onRefresh()被调用。

然而,当第一次RequestLocation()被调用时它成功通过即 in initState(),使用pull-to-refresh onRefresh()方法的后续调用似乎不会产生LocationLoaded()状态。

日志

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
Run Code Online (Sandbox Code Playgroud)

根据日志,第一次调用会同时打印RETRIEVED LOCATIONLOCATION LOADED,但在第二次RETRIEVED LOCATION之后没有其他任何事情发生。

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

Car*_*ein 12

我设法通过Equatable从我的StateEventBLoC 类中删除继承来解决这个问题。Equatable平等检查的实现导致 BlocListener 没有短路到相应的 if/else 块:

i.e. if (state is LocationLoaded)..
Run Code Online (Sandbox Code Playgroud)

有可能相等检查更严格,Equatable或者因为我在状态(纬度/经度)中传递两个坐标,它会导致相等检查失败。

州级:

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

class LocationLoaded extends GeolocationState {
}

class GeolocationUninitialized extends GeolocationState {
}
Run Code Online (Sandbox Code Playgroud)