I am using google maps in my project, i use it in different pages, but one page i have that i use tabviews, one of these tabs is the google map. however when ever i click on the tab the app crashes out, seems to be on android only it does this. I have tried it wih the SafeArea and without, make no difference. the first window opens just when touch to go to the map tab it crashes out.
Works fine on IOS, same code works on other pages but they dont have tabs
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
title: Text(
widget.amenityName,
style: GoogleFonts.kaushanScript(fontSize: 20, color: Colors.white),
),
bottom: const TabBar(
tabs: [
Tab(icon: Icon(Icons.home)),
Tab(icon: Icon(Icons.map)),
],
),
),
body: TabBarView(
children: [amenity(), showGoogleMap()],
),
),
);
}
Widget amenity() {
return FutureBuilder(
future: getAmenity(widget.amenityID),
builder: (BuildContext context,
AsyncSnapshot<AmenityDetailsDataSet> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
} else if (snapshot.error != null) {
return const Center(child: Text('an error occured!'));
} else {.................
}
Widget showGoogleMap() {
return SafeArea(
child: GoogleMap(
mapToolbarEnabled: false,
buildingsEnabled: false,
zoomControlsEnabled: true,
compassEnabled: true,
myLocationButtonEnabled: false,
scrollGesturesEnabled: true,
tiltGesturesEnabled: false,
trafficEnabled: false,
zoomGesturesEnabled: true,
rotateGesturesEnabled: false,
mapType: MapType.hybrid,
onMapCreated: _onMapCreated,
initialCameraPosition: CameraPosition(
target: widget.coords,
zoom: zoomLevel,
),
markers: _markers.values.toSet(),
),
);
}
Related
I want to hide the app bar and the widget at the bottom right away as soon as the screen scrolls. Also, I want to show what I hid as soon as I scroll to the top.
Also, because I have to put a widget under the Appbar, the widget is located in the bottom, and I put the tabbar under the Sliver Persistent Header widget.
The way I did it is to scroll as high as the app bar to hide it.
The code I wrote
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
bottom: false,
child: NestedScrollView(
key: _nestedScrollViewGlobalKey,
controller: _scrollController,
headerSliverBuilder: (context, innerBoxIsScrolled) {
return [
SliverAppBar(
backgroundColor: Colors.red.withOpacity(0.5),
elevation: 0.0,
title: Text('123123213'),
floating: true,
pinned: false,
snap: true,
// forceElevated: innerBoxIsScrolled,
expandedHeight: (BDSStyle.appBarHeight * 2),
toolbarHeight: (BDSStyle.appBarHeight * 2),
bottom: PreferredSize(
preferredSize: const Size.fromHeight(0),
child: Container(
height: BDSStyle.appBarHeight,
color: Colors.yellow.withOpacity(0.4),
),
),
),
SliverPersistentHeader(
pinned: true,
delegate: TabBarDelegate(_tabController),
),
];
},
body: _tabBarView(),
),
),
);
}
class TabBarDelegate extends SliverPersistentHeaderDelegate {
final TabController tabController;
const TabBarDelegate(this.tabController);
#override
Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
return BDSTabBar(
controller: tabController,
tabs: List.generate(PlaceCategory.values.length, (index) {
return PlaceCategory.values[index].koreanName;
}),
isScrollable: true,
);
}
#override
double get maxExtent => BDSStyle.tabBarHeight;
#override
double get minExtent => BDSStyle.tabBarHeight;
#override
bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) {
return false;
}
}
video link
Code Execution Image
The way I want to implement it
May be this code may help you.
DefaultTabController(
length: 2,
child: Scaffold(
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
title: Text("Application"),
floating: true,
pinned: true,
snap: true,
bottom: TabBar(
tabs: <Tab>[
Tab(text: "T"),
Tab(text: "B"),
], // <-- total of 2 tabs
),
),
];
},
body: TabBarView(
children: <Widget>[
Center(
child: Text(
'T Tab',
style: TextStyle(fontSize: 30),
)),
Center(
child: Text(
'B Tab',
style: TextStyle(fontSize: 30),
)),
],
),
),
),
)
I have a pair of widgets that generate a Google map and updates the user location but for some reason the padding seems to delay for a while, causing the MyLocation button to move into place instead of starting off in its correct position.
Is there any way to prevent this movement/delay in padding?
#override
Widget build(BuildContext context) {
return Scaffold(body: googleMapUI());
}
Widget googleMapUI() {
return Consumer<LocationProvider>(builder: (
consumerContext,
model,
child,
) {
if (model.locationPosition != null) {
return Column(
children: [
Expanded(
child: GoogleMap(
mapType: MapType.normal,
padding: const EdgeInsets.only(top: 40.0),
initialCameraPosition:
CameraPosition(target: model.locationPosition!, zoom: 18),
myLocationEnabled: true,
myLocationButtonEnabled: true,
onMapCreated: (GoogleMapController controller) async {
Provider.of<LocationProvider>(context, listen: false);
},
),
)
],
);
}
return Container(
child: const Center(
child: CircularProgressIndicator(),
),
);
});
}
Her is the code that I'm using kindly help me out.
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text(widget.videoItem.video.title),
),
body: Container(
child: YoutubePlayer(
controller: _controller,
showVideoProgressIndicator: true,
onReady: () {
print('Player is ready');
_isPlayerReady = true;
},),),);
Is there a way to change the default color of the myLocationButton in Google's APIs for iOS/Android? Can't seem to figure out how to do so.
#override
Widget build(BuildContext context) {
return new Scaffold(
body: _initialPosition == null
? Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
),
)
: Stack(children: [
GoogleMap(
mapType: MapType.normal,
initialCameraPosition: _currentPosition,
onMapCreated: (GoogleMapController controller) {
_setStyle(controller);
_controller.complete(controller);
},
zoomGesturesEnabled: true,
markers: _markers,
polylines: _polylines,
myLocationButtonEnabled: true,
myLocationEnabled: true,
mapToolbarEnabled: true,
),
]));
}
I'm trying to make fixed ScrollView with google map inside of FlexibleSpaceBar.
There's NestedScrollView with SliverAppBar and body content. Inside SliverAppBar is google map widget, app bar occupy the whole view of the device. There's also FloatingActionButton, which on press should scroll to the bottom of the view revealing body content of NestedScrollView and shifting map to app bar and vice versa. It technically works, there's a code if someone wants to see how it looks like:
#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();
}
}
The important part is here:
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);
},
),
),
),
];
},
There are 3 problems:
I dont understand how to prevent user from scrolling with gestures.
I want it to be controlled only by a scroll controller. I've tried to set physics of NestedScrollView to NeverScrollableScrollPhysics(), but it doesn't have any effect.
The map gesture detection inside scrollable widget behaving weirdly
You can't properly drag it and it seems to be only working with taps. In ListView, for example, it behaved fine with NeverScrollable physics.
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)
...
If anyone can help out with any of those or maybe know examples of such implementation I would highly appreciate it.
I crossed the same problem, and found the solution here.
background: GoogleMap(
gestureRecognizers: [
Factory<OneSequenceGestureRecognizer>(
() => EagerGestureRecognizer(),
),
].toSet(),