【问题标题】:Flutter error on a PageView with GoogleMaps Screen带有 GoogleMaps 屏幕的 PageView 上的颤振错误
【发布时间】:2022-01-12 11:50:10
【问题描述】:

我在 Flutter 中有一个特殊的问题,这种情况是,在一个包含 appbar、body 和 bottomBar 的页面中,在 body 中我有一个包含 3 个页面的页面视图。第一个带有地图,第二个和第三个带有元素列表。 例如,如果将页面更改为第二个 -> 第三个,一切正常,但是当我使用 GoogleMap 页面执行此操作时,从一页跳转到下一页后,设备中的所有屏幕都会变白一秒钟,就像重建一样。

似乎当我将页面从地图页面更改为另一个页面时,GoogleMaps 会重建所有页面。有什么想法吗?

谢谢:

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();
        },
        myLocationEnabled: true,
        markers: _.markers,
        onCameraIdle: _.manager!.updateMap,
        onCameraMove: (position) async {
          if (_.mapControllerCompleter.isCompleted) {
            if (_.markers.isEmpty) {
              _.fillAllMarkers();
            }
            _.manager!.onCameraMove(position);
            await _.showItemsInTheMapCamera(position, _.mapControllerCompleter);
          }
        },
      ),
    );
  }

'''

视频: Yo can see, when I go from map page to another one, a white screen refresh all the aplication

【问题讨论】:

  • 谢谢布拉德!看到更正后的评论,不好意思

标签: android ios json flutter graphql


【解决方案1】:

尝试将您的 mapExplorationPageallMyGoogleMapsObservationsPageallMapGoogleMapsObservationsPage 小部件分成单独的小部件,并将 AutomaticKeepAliveClientMixin 添加到每个小部件中,因为它应该添加到页面视图小部件而不是父主页小部件中

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;
}

旁注,强烈建议将小部件分成它们自己的小部件,而不是创建构建方法,以提高性能和代码可读性,因此请始终尝试这样做。 Check out this video from the Flutter about this issue

【讨论】:

  • 嗨 Roaa,感谢您的帮助!我尝试了您的想法,但问题仍然存在。我需要解释一下,在我的项目中,我有一个主页,在这个主页中,我有一个带有 5 个页面的 pageView。 (X,地图位置,X,X,X)。在 mapLocations 我有地图当前的 PageView 问题。所以它是一个 PageView,在一个 PageView 里面。也许有了这些信息更容易找到解决方案。目前,我按照您所说的方式在主页和 MapLocation 中的 withgets 中划分了浏览量,但是当我更改 pageMapView 屏幕时,白色窗口仍然存在。还有什么想法吗?再次感谢您!
  • 能否请您添加问题中发生的屏幕记录?
  • 是的 roaa,我刚刚添加了一个带有问题的 gif!
猜你喜欢
  • 2020-11-08
  • 2019-11-05
  • 2020-10-10
  • 2019-11-14
  • 2021-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-25
相关资源
最近更新 更多