Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Only last map built is usable when there are multiple instances #54

Closed
LjubiTech-Maxko opened this issue Jan 23, 2023 · 9 comments
Closed
Assignees
Labels
bug Something isn't working

Comments

@LjubiTech-Maxko
Copy link
Contributor

When creating multiple map instances all map controllers are working with the data from the map which was created last. The issue can be observed with the following reproduction code.

import 'package:flutter/material.dart';
import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late final PageController _pageController;

  void _switchPage(int page) {
    _pageController.jumpToPage(_page);
  }

  @override
  void initState() {
    super.initState();
    _pageController = PageController();
  }

  @override
  void dispose() {
    _pageController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('Mapbox Example')),
        body: Stack(
          children: [
            PageView(
              controller: _pageController,
              physics: const NeverScrollableScrollPhysics(),
              children: const [
                MapPage(),
                MapPage(),
                MapPage(),
              ],
            ),
            Align(
              alignment: Alignment.bottomCenter,
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  PageSwitch(page: 0, bgColor: Colors.red, onTap: _switchPage),
                  PageSwitch(page: 1, bgColor: Colors.green, onTap: _switchPage),
                  PageSwitch(page: 2, bgColor: Colors.blue, onTap: _switchPage),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

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

  @override
  State<MapPage> createState() => _MapPageState();
}

class _MapPageState extends State<MapPage> with AutomaticKeepAliveClientMixin {
  late final MapboxMap _map;

  void _mapCreated(MapboxMap map) {
    _map = map;
  }

  void _getCameraState() async {
    final CameraState camState = await _map.getCameraState();
    print(camState.encode());
  }

  @override
  bool get wantKeepAlive => true;

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return Stack(
      clipBehavior: Clip.none,
      fit: StackFit.expand,
      children: [
        MapWidget(
          resourceOptions: ResourceOptions(accessToken: <add access token>),
          onMapCreated: _mapCreated,
        ),
        Align(
          alignment: Alignment.centerRight,
          child: GestureDetector(
            onTap: _getCameraState,
            child: Container(
              width: 50,
              height: 50,
              color: Colors.blue,
            ),
          ),
        ),
      ],
    );
  }
}

class PageSwitch extends StatelessWidget {
  const PageSwitch({
    Key? key,
    required this.page,
    required this.bgColor,
    required this.onTap,
  }) : super(key: key);

  final int page;
  final Color bgColor;
  final void Function(int) onTap;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () => onTap(page),
      child: SizedBox(
        width: 50,
        height: 50,
        child: DecoratedBox(
          decoration: BoxDecoration(color: bgColor),
          child: Center(child: Text('$page')),
        ),
      ),
    );
  }
}

Copy the code to main.dart file and run the app.

Steps to reproduce:

  1. Scroll the map to a random point and click the blue rectangle on the right to get the CameraState.
  2. Click the green rectangle on the bottom to switch to the second map and repeat the first step.
  3. Click the blue rectangle on the bottom to switch to third map and repeat the first step.

And then go to the first or the second map and click again the blue rectangle to get the CameraState and it will be the state from the map which was created last. This is happening with every action that can be done on the map.

@dawid-niedzwiecki
Copy link

Same issue

@yunikkk yunikkk self-assigned this Feb 3, 2023
@yunikkk yunikkk added the bug Something isn't working label Feb 3, 2023
@yunikkk
Copy link
Collaborator

yunikkk commented Feb 3, 2023

@LjubiTech-Maxko thanks for the report, looking into this one.

@LjubiTech-Maxko
Copy link
Contributor Author

LjubiTech-Maxko commented Feb 6, 2023

@yunikkk I tried to do some debuggin and the thing that caught my attention is the documentation for setMessageHandler for BasicMessageChannel which states:

Overrides any existing handler registration for (the name of) this channel.

Is it possible that the creation of the new map instances and setup of channels overrides the previous one because of the same name?

@dawid-niedzwiecki
Copy link

Is there a known ETA? This issue is currently blocking our release :(

@LjubiTech-Maxko
Copy link
Contributor Author

@yunikkk After some tests with assigning different ids at the end of the name for basic message channel i can confirm that this is in fact the issue.

@yunikkk
Copy link
Collaborator

yunikkk commented Feb 6, 2023

@yunikkk After some tests with assigning different ids at the end of the name for basic message channel i can confirm that this is in fact the issue.

Hey @LjubiTech-Maxko, thanks for checking, I had the same suspicion that the id's for PlatformChannels should be the issue. Fix should be straightforward, I'll post updates here.

@dawid-niedzwiecki
Copy link

@yunikkk After some tests with assigning different ids at the end of the name for basic message channel i can confirm that this is in fact the issue.

Hey @LjubiTech-Maxko, thanks for checking, I had the same suspicion that the id's for PlatformChannels should be the issue. Fix should be straightforward, I'll post updates here.

any updates? :D

@yunikkk
Copy link
Collaborator

yunikkk commented Feb 7, 2023

any updates? :D

The work on this bug is in progress, I'll share updates as soon as it'll be ready :)

@dawid-niedzwiecki
Copy link

Thanks a lot!

any updates? :D

The work on this bug is in progress, I'll share updates as soon as it'll be ready :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants