简体   繁体   English

Flutter Web Iframe html 元素错误重新加载

[英]Flutter Web Iframe html element error reload

I'm trying to insert Iframe from local HTML file.我正在尝试从本地 HTML 文件插入 iframe。 For this porpouse I created a StatefulWidget to render the html in a HtmlElementView.对于这个海豚,我创建了一个 StatefulWidget 来在 HtmlElementView 中呈现 html。 This snippet working well.这个片段运行良好。 I see the Iframe, it work, but it has a strange behavior: every time it re-init html on any setState or even onMousOver on a FlatButton.我看到了 Iframe,它可以工作,但它有一个奇怪的行为:每次它在任何 setState 上重新初始化 html 时,甚至在 FlatButton 上的 onMousOver 上。

Why?为什么? Tnks坦克

import 'dart:async';
import 'dart:html' as html;
import 'dart:js' as js;
import 'dart:js';
import 'dart:ui' as ui;

import 'package:flutter/material.dart';

class MapPlugin extends StatefulWidget {
  MapPlugin();

  _MapPluginState createState() => _MapPluginState();
}

class _MapPluginState extends State<MapPlugin> {
  String createdViewId = 'map_element';

  @override
  void initState() {
    ui.platformViewRegistry.registerViewFactory(
        createdViewId,
        (int viewId) => html.IFrameElement()
          ..width = '800'
          ..height = '400'
          ..src = "/assets/map.html"
          ..style.border = 'none');

    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        padding: EdgeInsets.symmetric(horizontal: 10),
        decoration: BoxDecoration(
            color: Colors.white,
            border: Border.all(color: Colors.grey[300], width: 1),
            borderRadius: BorderRadius.all(Radius.circular(5))),
        width: 200,
        height: 200,
        child: Directionality(
            textDirection: TextDirection.ltr,
            child: HtmlElementView(
              viewType: createdViewId,
            )));
  }
}

将 HtmlElementView 移到构建函数之外,并将其替换为在 initState 函数 matey 中初始化的变量。

That's because a known bug in the flutter web framework where every time that there is a setState or a redraw of any widget inside the view, will make also the IFrameElement reload.那是因为 Flutter Web 框架中的一个已知错误,每次在视图中存在 setState 或任何小部件的重绘时,都会重新加载 IFrameElement。 It is caused in your case by the shadow of the RaisedButton that, if pressed or hovered, will go outside the button and cover the iframe, making it reload.在您的情况下,这是由 RaisedButton 的阴影引起的,如果按下或悬停该阴影,它将超出按钮并覆盖 iframe,使其重新加载。 In fact, if you put the IFrame full screen size it will not give any problems at all outside resizing or calling setState Externally.实际上,如果您将 IFrame 置于全屏大小,则在调整大小或外部调用 setState 之外根本不会出现任何问题。

To solve temporarily the problem with buttons, you can wrap your clickable widget in a GestureDetector.要暂时解决按钮的问题,您可以将可点击的小部件包装在 GestureDetector 中。 That's because GestureDetector will not give any sort of animation when clicked or hovered, so it will not cover your frame and make it reload.这是因为 GestureDetector 在单击或悬停时不会提供任何类型的动画,因此它不会覆盖您的框架并使其重新加载。

This is an example working from one of my app:这是从我的应用程序之一工作的示例:

Builder(
  builder: (context) => GestureDetector(
    onTap: () {
      print("Back to previous screen");
      Navigator.of(context).maybePop();
    },
    child: RaisedButton(
      child: Row(
        children: <Widget>[
          Icon(Icons.arrow_back, color: Colors.black),
          Text("GO BACK")
        ],
      ),
      onPressed: null
    ),
  ),
),

Of course this means that you should also manage the disabled style version of your button当然,这意味着您还应该管理按钮的禁用样式版本

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM