Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter: how to keep widget with Google Map unchanged?

Tags:

I am using Google Maps for Flutter widget. In my app map is displayed via one of the tabs of BottomNavigationBar.

And I have the following problem:

  1. user is on Map's tab
  2. user changes tab (by tapping on another one)
  3. [PROBLEM] when user returns on Map's tab map redraws.

I would like to keep map as it is when user leaves Map's tab, so he can continue to work with it when he returns to it later on.

Tried to:

  • use PageStorage - without success.
  • make something like Singletone of Map's state - without success.
  • use AutomaticKeepAliveClientMixin (saw here), which looked promising, but still without success.

(I admit that I could have done something wrong)

Code of last attempt:

class MapScreen extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => MapScreenState();
}

class MapScreenState extends State<MapScreen> with AutomaticKeepAliveClientMixin {
  GoogleMapController mapController;

  @override
  bool get wantKeepAlive => true;

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return Scaffold(
        appBar: AppBar(
          title: const Text("Map"),
        ),
        body: GoogleMap(
          onMapCreated: _onMapCreated,
        )
    );
  }

  void _onMapCreated(GoogleMapController controller) {
      mapController = controller;
      updateKeepAlive();
  }
}

So, I just need a way to either keep MapScreen alive and unchanged, or to store its state somehow and restore it when user returns to MapScreen. Or something else which will solve the problem.

like image 989
AQRC Avatar asked Jan 13 '19 23:01

AQRC


People also ask

How do I embed a Google Map in Flutter?

To use Google Maps in your Flutter app, you need to configure an API project with the Google Maps Platform, following the Maps SDK for Android's Using API key, Maps SDK for iOS' Using API key, and Maps JavaScript API's Using API key.


2 Answers

Use IndexedStack

For example:

Class _ExamplePageState extends State<ExamplePage> {
  int _bottomNavIndex = 0;

  final List<Widget> _children = [
    WidgetOne(),
    WidgetTwo(),
    GoogleMap(),
  ]

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: IndexedStack(
        index: _bottomNavIndex,
        children: _children,
      ),
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: _bottomNavIndex,
        onTap: (index) {
          if (_bottomNavIndex == index) return;
          setState(() {
            _bottomNavIndex = index;
          });
        }
        items: [ ... ]
      ),
    );
  }
}
like image 80
AaronJ Avatar answered Sep 18 '22 15:09

AaronJ


Widget always rebuild after you change from page to page, so, try this , use a variable for GoogleMap and reuse if it's different from null.

    GoogleMap _map;

     @override
    Widget build(BuildContext context) {
      if (_map == null){
        _map =  GoogleMap(
            onMapCreated: _onMapCreated,
          );
      }
      return Scaffold(
          appBar: AppBar(
            title: const Text("Map"),
          ),
          body:_map,
      );
    }
like image 36
diegoveloper Avatar answered Sep 22 '22 15:09

diegoveloper