【问题标题】:BlocProvider.of() called with a context that does not contain a Bloc/Cubit of type WeatherBlocBlocProvider.of() 调用的上下文不包含 WeatherBloc 类型的 Bloc/Cubit
【发布时间】:2021-05-25 17:38:29
【问题描述】:

我正在尝试将“我的位置”按钮添加到搜索屏幕。此按钮必须获取当前地理位置。但是出现了一些错误,按钮什么也没做,但它显示在搜索屏幕上。

错误:使用不包含 WeatherBloc 类型的 Bloc/Cubit 的上下文调用 BlocProvider.of()。

我的代码:

class MySearchDelegate extends SearchDelegate {
  String selectedResult;
  final Function callback;

  MySearchDelegate(this.callback);

  @override
  List<Widget> buildActions(BuildContext context) {
    return [
      IconButton(
        icon: Icon(Icons.my_location),
        onPressed: () {
          BlocProvider.of<WeatherBloc>(context)
              .add(WeatherCurrentPositionRequested());
        },
      ),
    ];
  }

 @override
 Widget buildLeading(BuildContext context) {
   return IconButton(
     icon: Icon(Icons.arrow_back),
     onPressed: () {
       Navigator.pop(context);
     },
   );
 }

 @override
 Widget buildResults(BuildContext context) {
   return Container(
     child: Center(
       child: Text(selectedResult),
     ),
   );
 }

@override
void showResults(BuildContext context) {
  selectedResult = query;
  callback(query);
  close(context, query);
}

@override
Widget buildSuggestions(BuildContext context) {
  List<String> searchResults =
      [query].where((element) => element.contains(query)).toList();

   return ListView.builder(
     itemCount: searchResults.length,
     itemBuilder: (context, index) {
       return ListTile(
         title: Text(searchResults[index]),
         onTap: () {
           selectedResult = searchResults[index];
           callback(selectedResult);
           Navigator.pop(context);
         },
       );
     },
   );
 }
}

区号:


class WeatherBloc extends Bloc<WeatherEvent, WeatherState> {
  WeatherBloc() : super(null) {
    add(WeatherCurrentPositionRequested());
  }

  @override
  Stream<WeatherState> mapEventToState(WeatherEvent event) async* {
    if (event is WeatherRequested) {
      yield* _newWeatherRequested(event);
    }
    if (event is WeatherCurrentPositionRequested) {
      yield* _newWeatherCurrentPositionRequested();
    }
  }

  Stream<WeatherState> _newWeatherRequested(WeatherRequested event) async* {
    yield WeatherLoadInProgress();
    try {
      final Weather weather = await WeatherService.fetchCurrentWeather(
          query: event.city, lon: event.lon, lat: event.lat);
      final List<Weather> hourlyWeather =
          await WeatherService.fetchHourlyWeather(
              query: event.city, lon: event.lon, lat: event.lat);
      yield WeatherLoadSuccess(weather: weather, hourlyWeather: hourlyWeather);
    } catch (_) {
      yield WeatherLoadFailure();
    }
  }

  Stream<WeatherState> _newWeatherCurrentPositionRequested() async* {
    LocationPermission permission = await checkPermission();
    if (permission == LocationPermission.whileInUse ||
        permission == LocationPermission.always) {
      Position lastKnownPosition = await getLastKnownPosition();
      if (lastKnownPosition != null) {
        add(WeatherRequested(
            lat: lastKnownPosition.latitude.toString(),
            lon: lastKnownPosition.longitude.toString()));
      } else {
        Position position =
            await getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
        add(WeatherRequested(
            lat: position.latitude.toString(),
            lon: position.longitude.toString()));
      }
    } else {
      await requestPermission();
      add(WeatherCurrentPositionRequested());
    }
  }
}

Main.dart 代码:

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (context) => WeatherBloc(),
      child: BlocBuilder<WeatherBloc, WeatherState>(
        builder: (context, state) {
          if (state is WeatherLoadSuccess) {
            return Scaffold(
              appBar: AppBar(
                elevation: 0,
                backgroundColor: Color.fromRGBO(71, 177, 230, 1),
                actions: [
                  IconButton(
                    icon: Icon(Icons.search),
                    onPressed: () {
                      showSearch(
                          context: context,
                          delegate: MySearchDelegate((query) {
                            BlocProvider.of<WeatherBloc>(context)
                                .add(WeatherRequested(city: query));
                          }));
                    },
                  )
                ],
              ),
              body: Padding(
                padding: EdgeInsets.only(top: 0),
                child: MainScreenWrapper(
                    weather: state.weather, hourlyWeather: state.hourlyWeather),
              ),
            );
          }
          return Scaffold(
            body: Center(
              child: CircularProgressIndicator(),
            ),
          );
        },
      ),
    );
  }
}

【问题讨论】:

  • 你能把暴露你的 BlocProvider 实例的代码贴出来吗?
  • @VictorEronmosele 我添加了 Bloc 代码。感谢您检查我的问题!
  • 您好,您在小部件树上方声明 BlocProvider 的位置怎么样?
  • 最有可能在你的 main.dart 中
  • MySearchDelegate 类上下文不同于 _MyHomePageState 类,您应该将 BlocProvider.of(context) 引用传递给您传递给 showSearch 函数的 MySearchDelegate 构造函数。希望你觉得它有用。

标签: flutter dart flutter-bloc


【解决方案1】:

您必须将BlocProvider.of&lt;WeatherBloc&gt;(context) 作为参数传递给 MySearchDelegate 类,然后在按下按钮时使用它,如下所示,或者您可以使用 Builder Widget 来使用上下文。

class MySearchDelegate extends SearchDelegate {
    
     final wheatherBlockProvider
    
     MySearchDelegate(this.callback,this.wheatherBlockProvider);
    
      @override
      List<Widget> buildActions(BuildContext context) {
        return [
          IconButton(
            icon: Icon(Icons.my_location),
            onPressed: () {
              
                 wheatherBlockProvider.add(WeatherCurrentPositionRequested());
            },
          ),
        ];
      }
    }


    
    IconButton(icon: Icon(Icons.search),
               onPressed: () {
               final weatherBlocProvier = BlocProvider.of<WeatherBloc>(context)
               showSearch(
                           context: context,
                           delegate: MySearchDelegate((query) {
                           weatherBlocProvier.add(WeatherRequested(city:query));
                              },weatherBlocProvier));
                        },
                      )

【讨论】:

    猜你喜欢
    • 2021-05-23
    • 2021-04-26
    • 2020-12-30
    • 2021-01-15
    • 2021-02-08
    • 2020-10-25
    • 2020-05-20
    • 2020-08-21
    • 2020-12-26
    相关资源
    最近更新 更多