“value.isInitialized”:不是 true || Flutter桌面错误

发布于 2025-01-13 04:44:40 字数 5988 浏览 1 评论 0原文

我正在为 flutter 桌面窗口开发 BlocklyBlockly 是编程语言 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;
  }
}

and here is my error in console
error

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

祁梦 2025-01-20 04:44:40

我在不同的场景中遇到了同样的问题,我所做的是对控制器内的其他函数执行 1 秒的 Future.delayed ,在我的情况下,异常在 setBackgroundColor 中抛出(这是在 initialize() 之后调用)说 value.isInitialized 在控制器初始化后不成立,这里是一个例子:

    Future.wait([
      _windowsWebViewController.initialize(),
      _windowsWebViewController.setBackgroundColor(Colors.transparent),
      _windowsWebViewController.setPopupWindowPolicy(WebviewPopupWindowPolicy.allow),
      _windowsWebViewController.loadUrl(element.url.toString().indexOf('.pdf') != -1
          ? 'https://docs.google.com/gview?embedded=true&url=${element.url.toString()}'
          : element.url.toString()),
    ]);

这里是解决方案:

Future.wait([
      _windowsWebViewController.initialize(),
    ]);

    Future.delayed(Duration(seconds: 1), () {

      _windowsWebViewController.setBackgroundColor(Colors.transparent);
      _windowsWebViewController.setPopupWindowPolicy(WebviewPopupWindowPolicy.allow);
      _windowsWebViewController.loadUrl(element.url.toString().indexOf('.pdf') != -1
      ? 'https://docs.google.com/gview?embedded=true&url=${element.url.toString()}'
          : element.url.toString());

    });

出于某种原因,即使我们初始化了控制器, 其余的即使我们使用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 after initialize()) saying value.isInitialized is not true after controller is initialized, here an example:

    Future.wait([
      _windowsWebViewController.initialize(),
      _windowsWebViewController.setBackgroundColor(Colors.transparent),
      _windowsWebViewController.setPopupWindowPolicy(WebviewPopupWindowPolicy.allow),
      _windowsWebViewController.loadUrl(element.url.toString().indexOf('.pdf') != -1
          ? 'https://docs.google.com/gview?embedded=true&url=${element.url.toString()}'
          : element.url.toString()),
    ]);

Here the solution:

Future.wait([
      _windowsWebViewController.initialize(),
    ]);

    Future.delayed(Duration(seconds: 1), () {

      _windowsWebViewController.setBackgroundColor(Colors.transparent);
      _windowsWebViewController.setPopupWindowPolicy(WebviewPopupWindowPolicy.allow);
      _windowsWebViewController.loadUrl(element.url.toString().indexOf('.pdf') != -1
      ? 'https://docs.google.com/gview?embedded=true&url=${element.url.toString()}'
          : element.url.toString());

    });

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文