flutter_osm_plugin: ^0.50.0-alpha.5 for web Cannot read properties of null (reading 'contentWindow') - openstreetmap

import 'package:flutter/material.dart';
import 'package:flutter_osm_plugin/flutter_osm_plugin.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
routes: {
'/main': (context) => MyHomePage(title: 'Title'),
'/osm': (context) => Osm(),
},
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const Osm(),
);
}
}
class Osm extends StatelessWidget {
const Osm({super.key});
#override
Widget build(BuildContext context) {
return Column(
children: [
TextButton(
onPressed: () {
Navigator.pushNamed(context, '/main');
},
child: const Text('Button'))
],
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late MapController controller;
#override
void dispose() {
controller.dispose();
super.dispose();
}
#override
void initState() {
controller = MapController(
initMapWithUserPosition: false,
initPosition: GeoPoint(latitude: 47.4358055, longitude: 8.4737324),
areaLimit: BoundingBox(
east: 10.4922941,
north: 47.8084648,
south: 45.817995,
west: 5.9559113,
),
);
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: OSMFlutter(
controller: controller,
trackMyPosition: false,
initZoom: 12,
minZoomLevel: 8,
maxZoomLevel: 14,
stepZoom: 1.0,
),
);
}
}
Add this line below 👇 in index.html in web folder
<script src="packages/flutter_osm_web/src/asset/map_init.js"></script>
When you first switch to a map widget, the map opens normally. If you return to the previous widget and go to the map again, an error occurs.
TypeError: Cannot read properties of null (reading 'contentWindow')
packages/flutter_osm_web/src/asset/map.js 182:65 setUpMap
packages/flutter_osm_web/src/controller/web_osm_controller.dart 141:35 initPositionMap
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 84:54 runBody
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 123:5 _async
packages/flutter_osm_web/src/controller/web_osm_controller.dart 137:31 initPositionMap
packages/flutter_osm_interface/src/map_controller/base_map_controller.dart 49:31
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 84:54 runBody
If you restart, the card is loaded.I.e. the card opens only after restart.
Sometimes writes console: ChromeProxyService: Failed to evaluate expression 'androidOSMLifecycle': InternalError: Expression evaluation in async frames is not supported. No frame with index 16..
How to solve such a problem? The problem occurs on initPositionMap.

Related

Unable to naviagte to another screen in flutter

I'm trying to take value from the method channel and using the value I'm trying to navigate another screen. When I try to navigate from TextButton onclick it's navigating but when I try to navigate from the value received by the method channel it's not navigating to another screen.
Example: I'm receiving openScreen1 from the method channel in the below code from methodCall.method and assigning the method to route variable but the page is not navigating
main_screen.dart
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:gg_app/screen1.dart';
import 'package:gg_app/screen2.dart';
class HomeScreen extends StatefulWidget {
static const routeName = "Home-Screen";
const HomeScreen({Key? key}) : super(key: key);
#override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
static const channel = MethodChannel('scribeemr.in/mic');
#override
void initState() {
// TODO: implement initState
channel.setMethodCallHandler(nativeMethodCallHandler);
super.initState();
}
Future<dynamic> nativeMethodCallHandler(MethodCall methodCall) async {
var route = methodCall.method;
await navigateTo(route, context);
}
Future<dynamic> navigateTo(String route, BuildContext context) async {
switch (route) {
case "openScreen1":
await Navigator.of(context).pushNamed(Screen1.routeName);
break;
case "openScreen2":
await Navigator.of(context).pushNamed(Screen2.routeName);
break;
default:
break;
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Home Screen")),
body: Column(
children: [
TextButton(
onPressed: () {
navigateTo("openScreen1", context);
},
child: Text("Screen 1")),
TextButton(
onPressed: () {
navigateTo("openScreen2", context);
},
child: Text("Screen 2")),
],
),
);
}
}
main.dart
import 'package:flutter/material.dart';
import 'package:gg_app/home_screen.dart';
import 'package:gg_app/screen1.dart';
import 'package:gg_app/screen2.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomeScreen(),
routes: {
HomeScreen.routeName: (context) => HomeScreen(),
Screen1.routeName: (context) => Screen1(),
Screen2.routeName: (context) => Screen2(),
},
);
}
}
screen1.dart
import 'package:flutter/material.dart';
class Screen1 extends StatefulWidget {
static const routeName = "Screen1";
const Screen1({ Key? key }) : super(key: key);
#override
State<Screen1> createState() => _Screen1State();
}
class _Screen1State extends State<Screen1> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Screen 1")),
);
}
}

Flutter VLC Player implementation

Is there something I am missing setting up the VLC on flutter? Only empty. No player seen just a blank page here is my flutter code, just followed from their documentation. Here is the code. I might miss something. Is there any alternative way to use the VLC plugin? I am new to Flutter. Thank you
import 'package:flutter_vlc_player/flutter_vlc_player.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({key}) : super(key: key);
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late VlcPlayerController _videoPlayerController;
#override
void initState() {
super.initState();
_videoPlayerController = VlcPlayerController.network(
'https://local.clift.mdu1.net/3ABN/index.m3u8',
hwAcc: HwAcc.FULL,
autoPlay: false,
options: VlcPlayerOptions(),
);
}
#override
void dispose() async {
super.dispose();
await _videoPlayerController.stopRendererScanning();
await _videoPlayerController.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: VlcPlayer(
controller: _videoPlayerController,
aspectRatio: 16 / 9,
placeholder: Center(child: CircularProgressIndicator()),
),
),
);
}
}```
try to add setstate in initState, or intime equal vlccontroller to VlcPlayerController.network

didUpdateWidget called immediately after initState in Flutter

According to Flutter Documentation:
didUpdateWidget called whenever the widget configuration changes
But, in the following code, didUpdateWidget is called immediately after initState on the first time.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Test(),
);
}
}
class Test extends StatefulWidget {
#override
_TestState createState() => _TestState();
}
class _TestState extends State<Test> {
#override
void initState() {
print("initState called");
super.initState();
}
#override
void didUpdateWidget(Test oldWidget) {
print("didUpdateWidget called");
super.didUpdateWidget(oldWidget);
}
#override
Widget build(BuildContext context) {
return Container();
}
}
// output
//
// initState called
// didUpdateWidget called
Can someone describe why this happens? and how can I compare the whole oldWidget with widget
Thank you
update
as #pskink mentioned, didUpdateWidget is not called immediately after initState, it's after the first build
Yet another question is why it is called after the first build with the following code:
print("didUpdateWidget called"); <--
super.didUpdateWidget(oldWidget); <--
but if I call print after super.didUpdateWidget(oldWidget);, it works fine.
In my test using Flutter 2.10.1 stable version, didUpdateWidget was only called after calling setState() to update the data displayed on the Widget. This behavior matches the description mentioned on the docs where the didUpdateWidget method is called whenever the widget configuration changes. After the didUpdateWidget method was called, build will then be called.
Here's how the flow can look like after calling setState() once.
initState()
build()
setState() called
didUpdateWidget()
build()
This can be replicated on this simple Flutter app.
import 'package:flutter/material.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: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
void initState() {
debugPrint('State initState');
super.initState();
}
#override
void didUpdateWidget(MyHomePage oldWidget) {
debugPrint('State didUpdateWidget');
super.didUpdateWidget(oldWidget);
}
#override
Widget build(BuildContext context) {
debugPrint('State Widget build');
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}

Async Listview update in flutter

I have created a program which displays a list view in build method and in init I have a async method.
That async method after 3 seconds adds an element in list and try to set State.
It is not working. My code is as follows.
calling async function in init may be wrong, i want to show the List view then make an async http call and then update the list view. and this should work even after push and pop.
import 'dart:async';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<String> europeanCountries = [
'Albania',
'Andorra',
'Armenia',
'Austria',
'Azerbaijan',
'Belarus',
'Belgium',
'Bosnia and Herzegovina'
];
int _counter = 0;
void _incrementCounter() async {
const ThreeSec = const Duration(seconds: 3);
Timer(ThreeSec, () {
europeanCountries.insert(0, "Testing");
print(europeanCountries);
});
setState(() {
_counter++;
});
}
#override
void initState() {
// TODO: implement initState
super.initState();
_incrementCounter();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: _myListView(context),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
Widget _myListView(BuildContext context) {
// backing data
return ListView.builder(
itemCount: europeanCountries.length,
reverse: true,
itemBuilder: (context, index) {
return ListTile(
title: Text(europeanCountries[index]),
);
},
);
}
}
Use timeout method handle and call setState method inside that method like following way
Timer(ThreeSec, () {
europeanCountries.insert(0, "Testing");
print(europeanCountries);
setState(() {
_counter++;
});
});

How catch the opening and closing of the drawer in flutter?

How can I catch the opening and closing of the drawer in flutter? In principle, two objects must be are used for this purpose: DrawerController, which "holds" the drawer and the drawerCallback. drawerCallback should track the opening and closing of the drawer, but the code that is discussed at https://github.com/flutter/flutter/issues/21272 and https://github.com/flutter/flutter/issues/23630 does not works. Anyone can advise something?
Update 2021-12:
Scaffold(
drawer: DrawerWidget(),
onDrawerChanged: (isDrawerOpen) {
if(isDrawerOpen) {
//drawer is open
} else {
//drawer is close
}
},
body: bodyWidget(),
)
You can first refer to other people's replies on stackoverflow here
My solve:
get Drawer status on DrawerWidget
initState() : open drawer
dispose() : close drawer
Stream drawer status by DrawerService Provider
see full code
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:provider/provider.dart';
void main() {
runApp(
MultiProvider(
providers: [
Provider(create: (_) => DrawerService()),
],
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
DrawerService _drawerService;
String drawerStatus = 'close';
#override
void initState() {
super.initState();
_drawerService = Provider.of(context, listen: false);
_listenDrawerService();
}
_listenDrawerService() {
_drawerService.status.listen((status) {
if(status) {
drawerStatus = 'open';
} else {
drawerStatus = 'close';
}
setState(() { });
});
}
#override
Widget build(BuildContext context) {
Color bgColor = Colors.yellow;
if(drawerStatus == 'open') {
bgColor = Colors.red;
}
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
drawer: DrawerWidget(),
body: Container(
decoration: BoxDecoration(color: bgColor),
height: 300,
child: Center(child: Text(drawerStatus),),
),
);
}
}
class DrawerWidget extends StatefulWidget {
#override
_DrawerWidgetState createState() => _DrawerWidgetState();
}
class _DrawerWidgetState extends State<DrawerWidget> {
DrawerService _drawerService;
#override
void initState() {
super.initState();
_drawerService = Provider.of(context, listen: false);
_drawerService.setIsOpenStatus(true);
}
#override
Widget build(BuildContext context) {
return Drawer(
child: Center(child: Text('drawer'),),
);
}
#override
void dispose() {
super.dispose();
_drawerService.setIsOpenStatus(false);
}
}
class DrawerService {
StreamController<bool> _statusController = StreamController.broadcast();
Stream<bool> get status => _statusController.stream;
setIsOpenStatus(bool openStatus) {
_statusController.add(openStatus);
}
}