我正在尝试在FlexibleSpaceBar内部使用谷歌地图制作固定的ScrollView。
有带有 SliverAppBar 和正文内容的 NestedScrollView。 SliverAppBar 内部是谷歌地图小部件,应用栏占据了设备的整个 View 。还有 FloatingActionButton,按下时应滚动到 View 底部,显示 NestedScrollView 的正文内容,并将 map 移动到应用栏,反之亦然。它在技术上是有效的,如果有人想看看它是什么样子的话,有一个代码:
@override
State<MapPage> createState() => MapPageState();
}
const LatLng _coordinates = LatLng(37.43296265331129, -122.08832357078792);
class MapPageState extends State<MapPage> with SingleTickerProviderStateMixin {
ScrollController _scrollController;
Completer<GoogleMapController> _controller = Completer();
double _scrollExtent;
bool _buttonState;
static final CameraPosition _kGooglePlex = CameraPosition(
target: _coordinates,
zoom: 14.4746,
);
@override
void initState() {
_buttonState = true;
_scrollController = ScrollController(initialScrollOffset: 0.0);
super.initState();
}
@override
void dispose() {
_scrollController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
_scrollExtent = MediaQuery.of(context).size.height;
return Scaffold(
floatingActionButton: FloatingActionButton(
child: Icon(Icons.keyboard_arrow_down),
backgroundColor: Colors.white,
foregroundColor: Colors.red,
onPressed: (){
if(_buttonState){
_scrollController.animateTo(_scrollExtent, duration: Duration(seconds: 1), curve: Curves.fastOutSlowIn);
_buttonState = false;
}
else{
_scrollController.animateTo(-_scrollExtent, duration: Duration(seconds: 1), curve: Curves.fastOutSlowIn);
_buttonState = true;
}
},
),
body: NestedScrollView(
controller: _scrollController,
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
expandedHeight: MediaQuery.of(context).size.height,
floating: false,
pinned: true,
flexibleSpace: FlexibleSpaceBar(
title: Text("Title",
style: TextStyle(
color: Colors.white,
fontSize: 16.0,
)),
background: GoogleMap(
mapType: MapType.normal,
initialCameraPosition: _kGooglePlex,
markers: _createMarker(),
onMapCreated: (GoogleMapController controller) {
_controller.complete(controller);
},
),
),
),
];
},
body: Container(
padding: EdgeInsets.all(24.0),
child: Text(
'Content'),
),
),
);
}
Set<Marker> _createMarker() {
return <Marker>[
Marker(
markerId: MarkerId("marker_1"),
position: _coordinates,
infoWindow: InfoWindow(title: 'Marker"'),
),
].toSet();
}
}
重要的部分在这里:
NestedScrollView(
controller: _scrollController,
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
expandedHeight: MediaQuery.of(context).size.height,
floating: false,
pinned: true,
flexibleSpace: FlexibleSpaceBar(
title: Text("Title",
style: TextStyle(
color: Colors.white,
fontSize: 16.0,
)),
background: GoogleMap(
mapType: MapType.normal,
initialCameraPosition: _kGooglePlex,
markers: _createMarker(),
onMapCreated: (GoogleMapController controller) {
_controller.complete(controller);
},
),
),
),
];
},
有3个问题:
- I dont understand how to prevent user from scrolling with gestures.
我希望它仅由滚动 Controller 控制。我尝试将 NestedScrollView 的物理设置为 NeverScrollableScrollPhysics(),但没有任何效果。
- The map gesture detection inside scrollable widget behaving weirdly
您无法正确拖动它,并且它似乎只能通过点击来使用。例如,在 ListView 中,它在 NeverScrollable 物理特性下表现良好。
- Every time it's getting rebuilt in app bar it seems to cause some sort of memory leak and I'm getting next warning.
E/flutter (10644): #0 _AsyncCompleter.complete (dart:async/future_impl.dart:39:31)
E/flutter (10644): #1 MapPageState.build.<anonymous closure>.<anonymous closure> (package:flutter_app/map_page2.dart:83:35)
E/flutter (10644): #2 _GoogleMapState.onPlatformViewCreated (package:google_maps_flutter/src/google_map.dart:259:14)
E/flutter (10644): <asynchronous suspension>
E/flutter (10644): #3 AndroidViewController._create (package:flutter/src/services/platform_views.dart:599:15)
...
如果有人可以帮助解决其中任何一个问题,或者知道此类实现的示例,我将不胜感激。
最佳答案
我遇到了同样的问题,并找到了解决方案here .
background: GoogleMap(
gestureRecognizers: [
Factory<OneSequenceGestureRecognizer>(
() => EagerGestureRecognizer(),
),
].toSet(),
关于flutter - 在 SliverAppBar 内实现 GoogleMap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56536065/