“value.isInitialized”:不是 true || Flutter桌面错误
我正在为 flutter 桌面窗口开发 Blockly(Blockly 是编程语言 JavaScript 的客户端库,用于创建基于块的可视化编程语言和编辑器)。 我正在使用 webview_windows
包在网络视图中显示“https://developers.google.com/blockly
”。
下面是我的代码
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:async';
import 'package:webview_windows/webview_windows.dart';
final navigatorKey = GlobalKey<NavigatorState>();
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(navigatorKey: navigatorKey, home: ExampleBrowser());
}
}
class ExampleBrowser extends StatefulWidget {
@override
State<ExampleBrowser> createState() => _ExampleBrowser();
}
class _ExampleBrowser extends State<ExampleBrowser> {
final _controller = WebviewController();
final _textController = TextEditingController();
bool _isWebviewSuspended = false;
@override
void initState() {
super.initState();
initPlatformState();
}
Future<void> initPlatformState() async {
try {
await _controller.initialize();
_controller.url.listen((url) {
_textController.text = URL;
});
await _controller.setBackgroundColor(Colors.transparent);
await _controller.setPopupWindowPolicy(WebviewPopupWindowPolicy.deny);
await _controller.loadUrl('https://developers.google.com/blockly');
if (!mounted) return;
setState(() {});
} on PlatformException catch (e) {
WidgetsBinding.instance?.addPostFrameCallback((_) {
showDialog(
context: context,
builder: (_) => AlertDialog(
title: Text('Error'),
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Code: ${e.code}'),
Text('Message: ${e.message}'),
],
),
actions: [
TextButton(
child: Text('Continue'),
onPressed: () {
Navigator.of(context).pop();
},
)
],
));
});
}
}
Widget compositeView() {
if (!_controller.value.isInitialized) {
return const Text(
'Not Initialized',
style: TextStyle(
fontSize: 24.0,
fontWeight: FontWeight.w900,
),
);
} else {
return Padding(
padding: EdgeInsets.all(20),
child: Column(
children: [
Card(
elevation: 0,
child: TextField(
decoration: InputDecoration(
hintText: 'URL',
contentPadding: EdgeInsets.all(10.0),
suffixIcon: IconButton(
icon: Icon(Icons.refresh),
onPressed: () {
_controller.reload();
},
)),
textAlignVertical: TextAlignVertical.center,
controller: _textController,
onSubmitted: (val) {
_controller.loadUrl(val);
},
),
),
Expanded(
child: Card(
color: Colors.transparent,
elevation: 0,
clipBehavior: Clip.antiAliasWithSaveLayer,
child: Stack(
children: [
Webview(
_controller,
permissionRequested: _onPermissionRequested,
),
StreamBuilder<LoadingState>(
stream: _controller.loadingState,
builder: (context, snapshot) {
if (snapshot.hasData &&
snapshot.data == LoadingState.loading) {
return LinearProgressIndicator();
} else {
return SizedBox();
}
}),
],
))),
],
),
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
tooltip: _isWebviewSuspended ? 'Resume webview' : 'Suspend webview',
onPressed: () async {
if (_isWebviewSuspended) {
await _controller.resume();
} else {
await _controller.suspend();
}
setState(() {
_isWebviewSuspended = !_isWebviewSuspended;
});
},
child: Icon(_isWebviewSuspended ? Icons.play_arrow : Icons.pause),
),
appBar: AppBar(
title: StreamBuilder<String>(
stream: _controller.title,
builder: (context, snapshot) {
return Text(
snapshot.hasData ? snapshot.data! : 'WebView (Windows) Example');
},
)),
body: Center(
child: compositeView(),
),
);
}
Future<WebviewPermissionDecision> _onPermissionRequested(
String url, WebviewPermissionKind kind, bool isUserInitiated) async {
final decision = await showDialog<WebviewPermissionDecision>(
context: navigatorKey.currentContext!,
builder: (BuildContext context) => AlertDialog(
title: const Text('WebView permission requested'),
content: Text('WebView has requested permission \'$kind\''),
actions: <Widget>[
TextButton(
onPressed: () =>
Navigator.pop(context, WebviewPermissionDecision.deny),
child: const Text('Deny'),
),
TextButton(
onPressed: () =>
Navigator.pop(context, WebviewPermissionDecision.allow),
child: const Text('Allow'),
),
],
),
);
return decision ?? WebviewPermissionDecision.none;
}
}
I am working on Blockly(Blockly is a client-side library for the programming language JavaScript for creating block-based visual programming languages and editors) for the flutter desktop windows.
I am using the webview_windows
package to display 'https://developers.google.com/blockly
' in a webview.
below is my code
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:async';
import 'package:webview_windows/webview_windows.dart';
final navigatorKey = GlobalKey<NavigatorState>();
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(navigatorKey: navigatorKey, home: ExampleBrowser());
}
}
class ExampleBrowser extends StatefulWidget {
@override
State<ExampleBrowser> createState() => _ExampleBrowser();
}
class _ExampleBrowser extends State<ExampleBrowser> {
final _controller = WebviewController();
final _textController = TextEditingController();
bool _isWebviewSuspended = false;
@override
void initState() {
super.initState();
initPlatformState();
}
Future<void> initPlatformState() async {
try {
await _controller.initialize();
_controller.url.listen((url) {
_textController.text = URL;
});
await _controller.setBackgroundColor(Colors.transparent);
await _controller.setPopupWindowPolicy(WebviewPopupWindowPolicy.deny);
await _controller.loadUrl('https://developers.google.com/blockly');
if (!mounted) return;
setState(() {});
} on PlatformException catch (e) {
WidgetsBinding.instance?.addPostFrameCallback((_) {
showDialog(
context: context,
builder: (_) => AlertDialog(
title: Text('Error'),
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Code: ${e.code}'),
Text('Message: ${e.message}'),
],
),
actions: [
TextButton(
child: Text('Continue'),
onPressed: () {
Navigator.of(context).pop();
},
)
],
));
});
}
}
Widget compositeView() {
if (!_controller.value.isInitialized) {
return const Text(
'Not Initialized',
style: TextStyle(
fontSize: 24.0,
fontWeight: FontWeight.w900,
),
);
} else {
return Padding(
padding: EdgeInsets.all(20),
child: Column(
children: [
Card(
elevation: 0,
child: TextField(
decoration: InputDecoration(
hintText: 'URL',
contentPadding: EdgeInsets.all(10.0),
suffixIcon: IconButton(
icon: Icon(Icons.refresh),
onPressed: () {
_controller.reload();
},
)),
textAlignVertical: TextAlignVertical.center,
controller: _textController,
onSubmitted: (val) {
_controller.loadUrl(val);
},
),
),
Expanded(
child: Card(
color: Colors.transparent,
elevation: 0,
clipBehavior: Clip.antiAliasWithSaveLayer,
child: Stack(
children: [
Webview(
_controller,
permissionRequested: _onPermissionRequested,
),
StreamBuilder<LoadingState>(
stream: _controller.loadingState,
builder: (context, snapshot) {
if (snapshot.hasData &&
snapshot.data == LoadingState.loading) {
return LinearProgressIndicator();
} else {
return SizedBox();
}
}),
],
))),
],
),
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
tooltip: _isWebviewSuspended ? 'Resume webview' : 'Suspend webview',
onPressed: () async {
if (_isWebviewSuspended) {
await _controller.resume();
} else {
await _controller.suspend();
}
setState(() {
_isWebviewSuspended = !_isWebviewSuspended;
});
},
child: Icon(_isWebviewSuspended ? Icons.play_arrow : Icons.pause),
),
appBar: AppBar(
title: StreamBuilder<String>(
stream: _controller.title,
builder: (context, snapshot) {
return Text(
snapshot.hasData ? snapshot.data! : 'WebView (Windows) Example');
},
)),
body: Center(
child: compositeView(),
),
);
}
Future<WebviewPermissionDecision> _onPermissionRequested(
String url, WebviewPermissionKind kind, bool isUserInitiated) async {
final decision = await showDialog<WebviewPermissionDecision>(
context: navigatorKey.currentContext!,
builder: (BuildContext context) => AlertDialog(
title: const Text('WebView permission requested'),
content: Text('WebView has requested permission \'$kind\''),
actions: <Widget>[
TextButton(
onPressed: () =>
Navigator.pop(context, WebviewPermissionDecision.deny),
child: const Text('Deny'),
),
TextButton(
onPressed: () =>
Navigator.pop(context, WebviewPermissionDecision.allow),
child: const Text('Allow'),
),
],
),
);
return decision ?? WebviewPermissionDecision.none;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我在不同的场景中遇到了同样的问题,我所做的是对控制器内的其他函数执行 1 秒的
Future.delayed
,在我的情况下,异常在 setBackgroundColor 中抛出(这是在initialize()
之后调用)说value.isInitialized
在控制器初始化后不成立,这里是一个例子:这里是解决方案:
出于某种原因,即使我们初始化了控制器, 其余的即使我们使用await来完成初始化,它内部的方法在控制器内部的值发生变化时也不会收到通知。
I had the same issue in a diffetent scenario, what I did was to do a
Future.delayed
of 1 second to the other functions inside the controller, in my case the exception is thrown inside setBackgroundColor (which was called right afterinitialize()
) sayingvalue.isInitialized
is not true after controller is initialized, here an example:Here the solution:
For some reason even though we initialize the controller, the rest of the methods inside of it do not get notify about the value inside the controller when it changes, even though we use await to complete the initialization.