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

[BUG] Map fails to reinitialize while in ListView #1288

Closed
Zverik opened this issue Jun 23, 2022 · 5 comments · Fixed by #1293
Closed

[BUG] Map fails to reinitialize while in ListView #1288

Zverik opened this issue Jun 23, 2022 · 5 comments · Fixed by #1293
Labels
bug This issue reports broken functionality or another error

Comments

@Zverik
Copy link
Contributor

Zverik commented Jun 23, 2022

When you put the FlutterMap inside a ListView, it can be hidden and then added anew. And it fails, because it sets a new state for a map controller, which is already initialized. Testing code is below: it adds 30 lines of text after the map. Scroll down and then back up again to see the error.

Mapybe mapController needs to be disposed properly?

Flutter_map 1.1.0, Flutter 3, Dart 2.17.

import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart' show LatLng;

void main() {
  runApp(const MaterialApp(
    title: 'Flutter Demo',
    home: MyHomePage(),
  ));
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Map in a ListView'),
      ),
      body: ListView(children: [
        SizedBox(
          height: 100.0,
          child: FlutterMap(
            options: MapOptions(
              center: LatLng(50, 30),
              zoom: 13,
              allowPanningOnScrollingParent: false,
            ),
            layers: [
              TileLayerOptions(
                urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
              ),
            ],
          ),
        ),
        for (int i = 1; i < 30; i++)
          Padding(
            padding: const EdgeInsets.all(20.0),
            child: Center(child: Text('Line $i', style: const TextStyle(fontSize: 20))),
          ),
      ]),
    );
  }
}
@Zverik Zverik added bug This issue reports broken functionality or another error needs triage This new bug report needs reproducing and prioritizing labels Jun 23, 2022
@ibrierley
Copy link
Collaborator

I think mapController is disposed of ok...

However, I suspect removing final from late final MapState mapState; in flutter_map_state.dart would do it...not sure if there's any implications there

@JaffaKetchup
Copy link
Member

As this as now had two reports, I'm going to remove the 'needs verification' label.

If you can try @ibrierley's suggestion @Zverik, that would be great :)

@JaffaKetchup JaffaKetchup added non-fatal and removed needs triage This new bug report needs reproducing and prioritizing labels Jun 28, 2022
@Zverik
Copy link
Contributor Author

Zverik commented Jun 29, 2022

I think @ibrierley's suggestion does not make sense, because it's the final field initializing in initState(), that checks out. The error was this:

Flutter: LateInitializationError: Field '_state@954051772' has already been initialized.

#0      LateError._throwFieldAlreadyInitialized (dart:_internal-patch/internal_patch.dart:194:5)
#1      MapControllerImpl._state= (package:flutter_map/src/map/map.dart:25:23)
#2      MapControllerImpl.state= (package:flutter_map/src/map/map.dart:29:5)
#3      FlutterMapState.initState (package:flutter_map/src/map/flutter_map_state.dart:38:19)
#4      StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4942:57)
#5      ComponentElement.mount (package:flutter/src/widgets/framework.dart:4781:5)
#6      Element.inflateWidget (package:flutter/src/widgets/framework.dart:3817:16)
#7      Element.updateChild (package:flutter/src/widgets/framework.dart:3551:18)
...

It can be fixed by removing the final keyword from lib/src/map/map.dart:25. And it is indeed weird, having a final property with a non-scoped setter. I have tested it, and it worked.

@ibrierley
Copy link
Collaborator

(Not sure if you meant it makes sense or doesn't make sense). However, I don't necessarily think it makes sense either way, even if it works :D. That's why I mentioned the implications.

The preferred way I guess would be to use your own mapController.

I suspect the problem with removing final, is maybe it stops one error, but previously I think the mapState was disposed (I assume)...are those disposed elements (any streams etc) reinstated, or is it in a slightly broken state, because other things weren't handled ? Do MapEvents and things like that still work correct...

@JaffaKetchup
Copy link
Member

Yeah it appears streams are still broken. I made a review on #1293 with a screenshot of the issue.

JaffaKetchup pushed a commit that referenced this issue Jul 20, 2022
* Fix late initialization error, see #1288

* Rework mapController life cycle

* Run dart format on changed files

* Add const modifier to the constructor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This issue reports broken functionality or another error
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants