我正在使用插件google_maps_flutter 1.2.0,我想实例化一个GoogleMapController来测试一些块的事件,其中控制器的值不能为空。 不幸的是,我不知道该怎么做,因为据我所知,GoogleMapController 无法在 GoogleMap() Widget 的“OnCreated”函数之外实例化。
GoogleMap(onMapCreated: (GoogleMapController controller) {
// Can only be instanciate here
},
);
不可能做这样的事:
GoogleMapController controller = new GoogleMapsController();
我只能这样做,并且控制器为空:
GoogleMapController controller;
我尝试了多种方法,但没有任何效果,有人可以帮助我吗?
首先,
GoogleMapController _googleMapController
在你的_WidgetState
中。GoogleMap(onMapCreated: (GoogleMapController controller) {
_googleMapController = controller;
}
);
创建 Google 地图后,您可以在小部件中的任何位置使用 _googleMapController。
你可以这样使用 - 在你的州:
final Completer<GoogleMapController> _controller =
Completer<GoogleMapController>();
在你的 GoogleMap() 小部件中就像这样
GoogleMap(
myLocationButtonEnabled: false,
zoomControlsEnabled: false,
onMapCreated: (GoogleMapController controller) =>
_googleMapController.complete(controller),
initialCameraPosition: _initialCameraPosition),
您可以在构建方法之前使用 use
_googleMapController? = controller;
,在您想要使用您的方法或您想要对实例执行的任何操作的地方制作一些 if 语句 (_googleMapController != null)
。
如果您使用的是 Flutter 2.5.3 及更高版本,您可以在变量声明前面添加一个 Late ,即
late GoogleMapController _googleMapController;
在您的谷歌地图小部件中,您可以照常使用该变量
onMapCreated: (controller) => _googleMapController = controller,
套餐:
map_page.feature
Feature: Map
Background:
Given The app is initialized
And The page is displayed
@success
Scenario: User is centered on their location
When I tap {Icons.my_location} button to get my current location
Then The map is centered on my location
di.dart
void setupLocator() {
// Any other injections...
sl.registerFactory<Completer<GoogleMapController>>(
() => Completer<GoogleMapController>(),
);
};
map_page.dart
class MapPage extends StatefulWidget {
const MapPage({super.key});
@override
State<MapPage> createState() => _MapPageState();
}
class _MapPageState extends State<MapPage> {
final Completer<GoogleMapController> _controller =
sl<Completer<GoogleMapController>>();
@override
Widget build(BuildContext context) {
return Scaffold(
body: BlocListener<MapBloc, MapState>(
listener: _onGetLocation,
child: GoogleMap(
onMapCreated: (controller) => _controller.complete(controller),
initialCameraPosition: const CameraPosition(
target: LatLng(0, 0),
zoom: 15,
),
),
),
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.my_location),
onPressed: () => context.read<MapBloc>().add(GetMyLocation()),
),
);
}
void _onGetLocation(BuildContext context, MapState state) async {
if (state is SuccessGetMyLocation) {
var controller = await _controller.future;
controller.animateCamera(CameraUpdate.newCameraPosition(
CameraPosition(target: state.latLng, zoom: 15),
));
}
}
}
test_helper.dart
@GenerateNiceMocks(<MockSpec>[
// Any other MockSpec...
MockSpec<Completer<GoogleMapController>>(),
MockSpec<GoogleMapController>(),
])
void main() {}
di_helper.dart
void setupDiHelper() {
// Any other injections...
sl.registerLazySingleton<Completer<GoogleMapController>>(
() => MockCompleter(),
);
};
the_app_is_initialized.dart
/// Usage: The app is initialized
Future<void> theAppIsInitialized(WidgetTester tester) async {
PatrolTester $ = PatrolTester(
tester: tester,
config: const PatrolTesterConfig(),
);
await setupDiHelper();
await $.pump();
}
the_page_is_displayed.dart
/// Usage: The page is displayed
Future<void> thePageIsDisplayed(WidgetTester $) async {
await $.pumpWidget(
MultiBlocProvider(
providers: [
BlocProvider<MapBloc>(
create: (context) => sl<MapBloc>(),
),
],
child: MaterialApp(
home: const MapPage(),
),
),
);
}
i_tap_button_to_get_my_current_location.dart
/// Usage: I tap {Icons.my_location} button to get my current location
Future<void> iTapButtonToGetMyCurrentLocation(
WidgetTester $, IconData icon) async {
var state = SuccessGetMyLocation(Position.fromMap(decode(Fixture.position)));
when(sl<MapBloc>().state).thenReturn(state);
// Create a mock GoogleMapController
final mockController = MockGoogleMapController();
// Stub the Completer's future to return the mock controller
final completer = sl<Completer<GoogleMapController>>();
when(completer.future).thenAnswer((_) async => mockController);
// Stub the animateCamera method on the mock controller
when(mockController.animateCamera(any)).thenAnswer((_) async => {});
await $.tap(find.byIcon(icon));
await $.pump();
}
the_map_is_centered_on_my_location.dart
/// Usage: The map is centered on my location
Future<void> theMapIsCenteredOnMyLocation(WidgetTester $) async {
var controller = await sl<Completer<GoogleMapController>>().future;
// Mock the position
var position = Position.fromMap(decode(Fixture.position));
var mockedLatLng = LatLng(position.latitude, position.longitude);
var mockedScreenCoordinate = const ScreenCoordinate(x: 0, y: 0);
// Add a stub for the getLatLng method
when(controller.getLatLng(mockedScreenCoordinate))
.thenAnswer((_) async => mockedLatLng);
var latLng = await controller.getLatLng(mockedScreenCoordinate);
expect(latLng, equals(mockedLatLng));
}
hooks.dart
abstract class Hooks {
const Hooks._();
static FutureOr<void> beforeEach(String title, [List<String>? tags]) {
if (tags?.contains('success') ?? false) {
provideDummy<MapState>(
SuccessGetMyLocation(Position.fromMap(decode(Fixture.position))),
);
} else if (tags?.contains('failure') ?? false) {
}
}
static FutureOr<void> beforeAll() {}
static FutureOr<void> afterEach(
String title,
bool success, [
List<String>? tags,
]) {}
static FutureOr<void> afterAll() {}
}
map_page_test.dart
此文件是使用
map_page.feature
从
dart run build_runner build
自动生成的