简体   繁体   中英

Flutter error on a PageView with GoogleMaps Screen

I have a special isue in Flutter, The case is, in a page with appbar, body, and bottomBar, in the body I have a page view with 3 pages. First one with a map, second and third one with a list of elements. If change the page second -> third for example, everything goes fine, but when I do it with the GoogleMap page, after jump from one page to the next, all screen in the device turns white for a second, like a rebuild.

Seems like when I change page to another one from map page, the GoogleMaps rebuild all the page. Any idea about this?

Thank you:

Doctor: 
[√] Flutter (Channel stable, 2.8.1, on Microsoft Windows [Versión 10.0.19042.1415], locale es-ES)
[√] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
[√] Chrome - develop for the web
[√] Android Studio (version 4.1)
[√] VS Code (version 1.63.2)
[√] Connected device (3 available)

'''

class _HomeState extends State<PageViewLocalization>
    with AutomaticKeepAliveClientMixin {

  @override
  bool get wantKeepAlive => true;

  @override
  Widget build(BuildContext context) {
    //WidgetsBinding.instance!.addObserver(this);
    super.build(context);
    return Scaffold(
      appBar: appBar(widget._),
      backgroundColor: Styles.principalBackGroundColor,
      body: PageView(
        physics: const NeverScrollableScrollPhysics(),
        controller: widget._.localizationPageViewController,
        children: [
          mapExplorationPage(widget._),
          allMapGoogleMapsObservationsPage(widget._),
          allMyGoogleMapsObservationsPage(widget._),
        ],
      ),
    );
  }
appBar(HomeController _) {
    return AppBar(
      automaticallyImplyLeading: false,
      actions: [
        Center(
          child: Container(
            padding: const EdgeInsets.only(top: 12),
            margin: const EdgeInsets.only(bottom: 10),
            child: CustomSlidingSegmentedControl(
              fixedWidth: 60,
              padding: 8,
              children: {
                0: Icon(
                  Icons.map_outlined,
                  size: 14,
                  color: _.currentLocalizationPage == 0
                      ? _.enabledCustomSlidingSegmentedControl
                          ? Styles.minkaPrincipalColor
                          : Colors.grey
                      : Colors.grey,
                ),
                1: Icon(
                  Icons.list,
                  size: 14,
                  color: _.currentLocalizationPage == 1
                      ? Styles.minkaPrincipalColor
                      : Colors.grey,
                ),
                2: Icon(
                  Icons.person_outline,
                  size: 14,
                  color: _.currentLocalizationPage == 2
                      ? Styles.minkaPrincipalColor
                      : Colors.grey,
                ),
              },
              onValueChanged: (int value) async {
                if (value != 0 && _.boundsInicialized == false) {
                  _.boundsInicialized = true;
                  _.manager!.onCameraMove(_.cameraPositionOnInicializeMap);
                  await _.showItemsInTheMapCamera(
                      _.cameraPositionOnInicializeMap,
                      _.mapControllerCompleter);
                }

                if (_.enabledCustomSlidingSegmentedControl) {
                  _.currentLocalizationPage = value;
                  _.update();
                  _.localizationPageViewController.jumpToPage(
                    _.currentLocalizationPage,
                  );
                  // await _.localizationPageViewController.animateToPage(
                  //     _.currentLocalizationPage,
                  //     curve: Curves.easeIn,
                  //     duration: Duration(milliseconds: 500));
                }
              },
            ),
          ),
        ),
        const SizedBox(width: Styles.paddingValue / 2)
      ],
      backgroundColor: Styles.principalBackGroundColor,
      elevation: Styles.defaultElevation,
      title: Container(
        margin: const EdgeInsets.only(left: Styles.paddingValue / 2),
        child: Align(
          alignment: Alignment.centerLeft,
          child: SvgPicture.asset(
            "assets/images/ic_1231232.svg",
            width: 108,
            height: 30,
          ),
        ),
      ),
    );
  }

 mapExplorationPage(HomeController _) {
    Completer<GoogleMapController> _passInfoCompleter = Completer();

    return SizedBox(
      child: GoogleMap(
        myLocationButtonEnabled: true,
        zoomControlsEnabled: true,
        mapType: MapType.hybrid,
        initialCameraPosition: _.cameraPositionOnInicializeMap,
        onMapCreated: (GoogleMapController controller) async {
          if (!_.mapControllerCompleter.isCompleted) {
            mapController = controller;
            _.mapControllerCompleter.complete(controller);
            _.manager!.setMapId(controller.mapId);
            await _.showItemsInTheMapCamera(
                _.cameraPositionOnInicializeMap, _.mapControllerCompleter);
          } else {
            _passInfoCompleter.complete(controller);
            _.mapControllerCompleter = _passInfoCompleter;
            _.manager!.setMapId(controller.mapId);
          }
          // _.zoomEfect(); TODO ARREGLAR MAP OTRA PUTA VEZ
        },
        myLocationEnabled: true,
        markers: _.markers,
        onCameraIdle: _.manager!.updateMap,
        onCameraMove: (position) async {
          if (_.mapControllerCompleter.isCompleted) {
            if (_.markers.isEmpty) {
              _.fillAllMarkers();
            }
            _.manager!.onCameraMove(position);
            await _.showItemsInTheMapCamera(position, _.mapControllerCompleter);
          }
        },
      ),
    );
  }

'''

Try separating your mapExplorationPage & allMyGoogleMapsObservationsPage & allMapGoogleMapsObservationsPage widgets into separate widgets and add the AutomaticKeepAliveClientMixin to each one of them as it should be added to the page view widgets instead of the parent home widget

1)

class MapExplorationPage extends StatefulWidget {
  const MapExplorationPage({Key? key}) : super(key: key);

  @override
  _MapExplorationPageState createState() => _MapExplorationPageState();
}

class _MapExplorationPageState extends State<MapExplorationPage> with AutomaticKeepAliveClientMixin {
  @override
  Widget build(BuildContext context) {
    super.build(context);
    // ...
  }

  @override
  bool get wantKeepAlive => true;
}
class AllMapGoogleMapsObservationsPage extends StatefulWidget {
  const AllMapGoogleMapsObservationsPage({Key? key}) : super(key: key);

  @override
  _AllMapGoogleMapsObservationsPageState createState() => _AllMapGoogleMapsObservationsPageState();
}

class _AllMapGoogleMapsObservationsPageState extends State<AllMapGoogleMapsObservationsPage> with AutomaticKeepAliveClientMixin {
  @override
  Widget build(BuildContext context) {
    super.build(context);
    // ...
  }

  @override
  bool get wantKeepAlive => true;
}
class AllMyGoogleMapsObservationsPage extends StatefulWidget {
  const AllMyGoogleMapsObservationsPage({Key? key}) : super(key: key);

  @override
  _AllMyGoogleMapsObservationsPageState createState() => _AllMyGoogleMapsObservationsPageState();
}

class _AllMyGoogleMapsObservationsPageState extends State<AllMyGoogleMapsObservationsPage> with AutomaticKeepAliveClientMixin {
  @override
  Widget build(BuildContext context) {
    super.build(context);
    // ...
  }

  @override
  bool get wantKeepAlive => true;
}

Side note, separating widget into their own widgets rather than creating build methods is strongly recommended for performance and code readability so always try to do that. Check out this video from the Flutter about this issue

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM