【发布时间】: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