[英]BlocProvider.of() called with a context that does not contain a Bloc/Cubit of type WeatherBloc
I'm trying to add a "My Location" button to search screen.我正在尝试将“我的位置”按钮添加到搜索屏幕。 This button must get current geolocation.
此按钮必须获取当前地理位置。 But there is some error comming up and button does nothing, but it shows on search screen.
但是出现了一些错误,按钮什么也不做,但它显示在搜索屏幕上。
Error: BlocProvider.of() called with a context that does not contain a Bloc/Cubit of type WeatherBloc.错误:使用不包含 WeatherBloc 类型的 Bloc/Cubit 的上下文调用 BlocProvider.of()。
My code:我的代码:
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);
},
);
},
);
}
}
Bloc code:集团代码:
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 code: 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(),
),
);
},
),
);
}
}
You have to pass BlocProvider.of<WeatherBloc>(context)
as a parameter to MySearchDelegate class and then use it on button pressed like below or you can use Builder Widget to use context.您必须将
BlocProvider.of<WeatherBloc>(context)
作为参数传递给 MySearchDelegate class,然后在按下的按钮上使用它,如下所示,或者您可以使用 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));
},
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.