【发布时间】:2020-10-13 16:54:45
【问题描述】:
我想在 Flutter 的多个不同页面中重用同一个 StatefulWidget。在下面的示例中,我希望不为每个页面重建 MyGoogleMap。当我使用 TabBar 导航到第二页时,它使用了另一个新版本的 MyGoogleMap。我尝试使用全局键并加载相同的实例,但只加载了几秒钟,然后我收到相同键被使用两次的错误。
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:location/location.dart';
const double CAMERA_TILT = 0;
const double CAMERA_BEARING = 0;
const LatLng SOURCE_LOCATION = LatLng(42.747932, -71.167889);
const LatLng DEST_LOCATION = LatLng(37.422, -122.084);
class MyGoogleMap extends StatefulWidget {
const MyGoogleMap({Key key}) : super(key: key); // NEW CONSTRUCTOR
@override
State<MyGoogleMap> createState() => MyGoogleMapState();
}
class MyGoogleMapState extends State<MyGoogleMap> {
double CAMERA_ZOOM = 16;
CameraPosition initialCameraPosition;
//Map controller
Completer<GoogleMapController> _controller = Completer();
GoogleMapController controller;
//Markers
Set<Marker> _markers = Set<Marker>();
Set<Polyline> _polylines = Set<Polyline>();
// the user's initial location and current location
LocationData currentLocation;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
initialCameraPosition = CameraPosition(
zoom: CAMERA_ZOOM,
tilt: CAMERA_TILT,
bearing: CAMERA_BEARING,
target: SOURCE_LOCATION);
if (currentLocation != null) {
initialCameraPosition = CameraPosition(
target: LatLng(currentLocation.latitude, currentLocation.longitude),
zoom: CAMERA_ZOOM,
tilt: CAMERA_TILT,
bearing: CAMERA_BEARING);
}
return Container(
height: 400,
child: GoogleMap(
mapToolbarEnabled: false,
myLocationEnabled: true,
compassEnabled: true,
tiltGesturesEnabled: false,
markers: _markers,
polylines: _polylines,
mapType: MapType.normal,
initialCameraPosition: initialCameraPosition,
onMapCreated: (GoogleMapController controller) {
//Change this to change styles
// controller.setMapStyle(Utils.DarkStyle);
_controller.complete(controller);
})
);
}
}
@override
Widget build(BuildContext context) {
SizeConfig().init(context);
return Scaffold(
resizeToAvoidBottomPadding: false,
extendBodyBehindAppBar: true,
extendBody: true,
body: Container(
height: SizeConfig.blockSizeVertical * 100,
width: SizeConfig.blockSizeHorizontal * 100,
decoration: (selectedNavigationIndex == 3
? backgrounds.dark
: backgrounds.normal),
child: Column(children: <Widget>[
TopBar(),
IndexedStack(
children: <Widget>[
MyGoogleMap(),
MyGoogleMap(),
],
index: selectedNavigationIndex,
),
BottomBar(
this.selectedNavigationIndexCallback, selectedNavigationIndex),
])),
);
}
@override
Widget build(BuildContext context) {
SizeConfig().init(context);
return Scaffold(
resizeToAvoidBottomPadding: false,
extendBodyBehindAppBar: true,
extendBody: true,
body: Container(
height: SizeConfig.blockSizeVertical * 100,
width: SizeConfig.blockSizeHorizontal * 100,
decoration: (selectedNavigationIndex == 3
? backgrounds.dark
: backgrounds.normal),
child: Column(children: <Widget>[
TopBar(),
IndexedStack(
children: <Widget>[
MyGoogleMap(key: _MyGoogleMapState),
MyGoogleMap(key: _MyGoogleMapState),
],
index: selectedNavigationIndex,
),
BottomBar(
this.selectedNavigationIndexCallback, selectedNavigationIndex),
])),
);
}
【问题讨论】:
-
绝对有更好的方法,但如果你找不到任何东西,你可能会使用 Provider 或 GetIt 并以这种方式获取相同的小部件,尽管提供小部件的状态而不是实际的小部件会好得多。
-
嗨,也许可以为我提供一些示例代码。如何将小部件的状态传递给另一个小部件?