简体   繁体   中英

Flutter Web Iframe html element error reload

I'm trying to insert Iframe from local HTML file. For this porpouse I created a StatefulWidget to render the html in a HtmlElementView. 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.

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. 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. In fact, if you put the IFrame full screen size it will not give any problems at all outside resizing or calling setState Externally.

To solve temporarily the problem with buttons, you can wrap your clickable widget in a 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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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