flutter-mapbox-gl / maps

A Mapbox GL flutter package for creating custom maps
Other
1.04k stars 504 forks source link

Navigation issue when useHybridComposition = true on Android 9 #954

Open cohenadair opened 2 years ago

cohenadair commented 2 years ago

Using the latest master (b29092ea395eb2c8d93af97945565e516a084b85) results in the map showing in front of any navigation. For example, showing an input form when the map is open, will briefly show the form (flashed on the screen), then what appears to be a new map instance shown in front of it.

Reproducible on Android 9. Based on by testing, everything works as expected iOS 15 and Android 12. Workaround is to set useHybridComposition to false.

@yoavrofe, I'm tagging you because you submitted the useHybridComposition change and thought you might be able to offer some insight.

Example app:

mapbox_gl:
  git: https://github.com/flutter-mapbox-gl/maps.git
import 'package:flutter/material.dart';
import 'package:mapbox_gl/mapbox_gl.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Mapbox Bug',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(),
    );
  }
}

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

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

class _MyHomePageState extends State<MyHomePage> {
  @override
  void initState() {
    super.initState();
    MapboxMap.useHybridComposition = true;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          MapboxMap(
            accessToken: "access_token",
            initialCameraPosition: const CameraPosition(target: LatLng(0, 0)),
          ),
          Center(
            child: FloatingActionButton(
              child: const Icon(Icons.add),
              onPressed: () {
                Navigator.of(context).push(
                  MaterialPageRoute(
                    builder: (context) => const Scaffold(
                      body: Center(child: Text("New Page")),
                    ),
                  ),
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}
felix-ht commented 2 years ago

https://github.com/flutter-mapbox-gl/maps/blob/b29092ea395eb2c8d93af97945565e516a084b85/example/lib/main.dart#L78

That how its solved in the example. I wasn't expecting such issues on android <= 9.

For me we have three options:

  1. Fix issue with hybrid Composition on old version
  2. Set normal composition as the default
  3. Automatically set proper composition

1) might be impossible as i could very well be an upstream issue. 2) would be a quick fix so people who want to use it can opt in with a solution similar to the one in the example. And 3) would be the most elegant solution but might be somewhat tricky to do in a robust way as of the async nature of getting android versions. (a future builder that waits for the Android version might do the trick)

So i would suggest to do a PR with 2) as this is a quick fix - as we try to workout either 1) or 3)

cohenadair commented 2 years ago

I guess my question should be what are, if any, the side effects for doing 2 for Android 12? IIRC, one of the reasons hybrid composition was added was because not using it could cause issues on Android 12.

felix-ht commented 2 years ago

I guess my question should be what are, if any, the side effects for doing 2 for Android 12? IIRC, one of the reasons hybrid composition was added was because not using it could cause issues on Android 12.

Yeah it would keep having some issues with e.g. rotation. But at least it would not be new issues surprising devs, and they would be less critical than this.

We can also put some example code into the readme or even add a static function to initialize composition that the dev can call when the app is starting up

srmncnk commented 2 years ago

We are using hybrid mode on our dedicated Android 9 device. Have been doing so since before this repo was forked from tobrun's original repo. And we've also switched to hybrid mode ourselves before it was implemented because of two reasons:

Recently we tried to use your repository but found the same issue of map being displayed all the time, even if you push a page infront of it. We are able to render a widget on top of mapbox, but whole page for some reason does not render. So we switched back to our repo for the time being. Meaning - we do use hybrid mode successfully on Android 9 but from the diff it is not clear, why it behaves correctly and why your repo does not. We can make it publically available if anybody is interested.

Please don't close this issue before resolving it.

felix-ht commented 2 years ago

We are using hybrid mode on our dedicated Android 9 device. Have been doing so since before this repo was forked from tobrun's original repo. And we've also switched to hybrid mode ourselves before it was implemented because of two reasons:

  • stopped crashes on our dedicated Andorid device, causing it to reboot (!)
  • significantly faster rendering

Recently we tried to use your repository but found the same issue of map being displayed all the time, even if you push a page infront of it. We are able to render a widget on top of mapbox, but whole page for some reason does not render. So we switched back to our repo for the time being. Meaning - we do use hybrid mode successfully on Android 9 but from the diff it is not clear, why it behaves correctly and why your repo does not. We can make it publically available if anybody is interested.

Please don't close this issue before resolving it.

yeah that might be interesting indeed

jgrandchavin commented 2 years ago

Hello everyone 👋

I have found a fix for the map appear on all pages when useHybridComposition is false

You have to add to replace private final MapboxMapOptions options = new MapboxMapOptions().attributionEnabled(true); by private final MapboxMapOptions options = new MapboxMapOptions().textureMode(true).attributionEnabled(true);

in MapboxMapBuilder.java line 17

SwiftyFlow commented 2 years ago

Must be related https://github.com/flutter-mapbox-gl/maps/issues/1008#issue-1208406765

thanks for the .textureMode(true) that's what saved me BUT now I get 1000s of prints...