【问题标题】:Can i use two iframes on Flutter web?我可以在 Flutter web 上使用两个 iframe 吗?
【发布时间】:2020-12-04 00:33:15
【问题描述】:

我是 Flutter 的新手,我正在开发一个用于学习的小网页。 我想使用两个 iframe 放置一个 google 地图和 facebook feed。

我的代码基于 Wangoo 的代码: https://medium.com/flutter-community/flutter-web-and-iframe-f26399aa1e2a

如果我只使用一个 iframe,它可以完美运行,但如果我使用第二个,它具有第一个的源,而第一个不显示任何内容。像这样: https://imgur.com/a/eWq2GU5

已经测试了其他一些包,但大多数不兼容网络,或者只是不能使用带有类似链接的 iframe

这是我的代码:

import 'package:flutter/material.dart';

//ignore: avoid_web_libraries_in_flutter
import 'dart:html';
import 'dart:ui' as ui;

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  String linkMaps = 'https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d10500.899078315058!2d2.29133003705264!3d48.853924135746475!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x47e6701f7e8337b5%3A0xa2cb58dd28914524!2sEiffel%20Tower%2C%20Par%C3%ADs%2C%20Francia!5e0!3m2!1ses-419!2smx!4v1597383453609!5m2!1ses-419!2smx';
  String linkFB = 'https://www.facebook.com/plugins/page.php?href=https%3A%2F%2Fwww.facebook.com%2FTourEiffel&tabs=timeline&width=340&height=500&small_header=false&adapt_container_width=true&hide_cover=false&show_facepile=true&appId';

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
    body:  Container(
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Container(color: Colors.red, child: new IframeScreen(400, 400, linkMaps)),
          Container(color: Colors.blue, child: new IframeScreen(340, 400, linkFB))
        ],
      ),
    )
    );
  }
}
 
//--------------------------------------------------------------------------I
//Code based on: Aseem Wangoo (Mar-22)                                      I
//https://medium.com/flutter-community/flutter-web-and-iframe-f26399aa1e2a  I
//--------------------------------------------------------------------------I

// ignore: must_be_immutable
class IframeScreen extends StatefulWidget {
  double w;
  double h;
  String src;

  IframeScreen(double _w, double _h, String _src){
    this.w = _w;
    this.h = _h;
    this.src = _src;
  }

  @override
  _IframeScreenState createState() => _IframeScreenState(w, h, src);
}


class _IframeScreenState extends State<IframeScreen> {
  Widget _iframeWidget;
  final IFrameElement _iframeElement = IFrameElement();
  double _width;
  double _height;
  String _source;

  _IframeScreenState(double _w, double _h, String _src){
    _width = _w;
    _height = _h;
    _source = _src;
  }

  @override
  void initState() {
    super.initState();
    _iframeElement.src = _source;
    _iframeElement.style.border = 'none';

    // ignore: undefined_prefixed_name
    ui.platformViewRegistry.registerViewFactory(
      'iframeElement',
    (int viewId) => _iframeElement,
    );

    _iframeWidget = HtmlElementView(
      key: UniqueKey(),
      viewType: 'iframeElement',
    );
  }


  @override
  Widget build(BuildContext context) {
    return SizedBox(
      height: _height,
      width: _width,
      child: _iframeWidget,
    );
  }
}

谢谢:)

【问题讨论】:

    标签: flutter dart iframe flutter-web dart-html


    【解决方案1】:

    是的,您可以在 Flutter 网络中使用两个 iframe。

    但如果你那样做,它就行不通了。 相反,在我的代码中,我传递了链接。

    只需使用两个具有不同 viewID 的 IframeWidget。 在这里,我用它在我的网站上获取了我的社交媒体项目。

    GraphrMedia (Go to Work Section) [Might take 12 sec time to load.]

    class _IframeScreenState extends State<IframeScreen> {
    Widget _iframeWidget;
    Widget _iframeWidget2;
    final IFrameElement _iframeElement = IFrameElement();
    final IFrameElement _iframeElement2 = IFrameElement();
    List<width> _width;
    double _height;
    List<String> _source;
    
    _IframeScreenState(List<width> _w, double _h, List<String> _src,){
    _width = _w;
    _height = _h;
    _source = _src;
    }
    
    @override
    void initState() {
    super.initState();
    _iframeElement.src = _source[0];
    _iframeElement.style.border = 'none';
    
    _iframeElement2.src = _source[1];
    _iframeElement2.style.border = 'none';
    
    // ignore: undefined_prefixed_name
    ui.platformViewRegistry.registerViewFactory(
      'iframeElement',
          (int viewId) => _iframeElement,
    );
    // ignore: undefined_prefixed_name
    ui.platformViewRegistry.registerViewFactory(
      'iframeElement2',
          (int viewId) => _iframeElement2,
    );
    
    _iframeWidget = HtmlElementView(
      key: UniqueKey(),
      viewType: 'iframeElement',
    );
    _iframeWidget2 = HtmlElementView(
      key: UniqueKey(),
      viewType: 'iframeElement2',
    );
    }
    
    
    @override
    Widget build(BuildContext context) {
     return Row(
        mainAxisAlignment: MainAxisAlignment.center,
     children:[
      Container(
        color: Colors.blue,
        child: SizedBox(
          height: _height,
          width: _width[0],
          child:_iframeWidget[0],
        ),
      ), Container(
        color: Colors.red,
        child: SizedBox(
          height: _height,
          width: _width[1],
          child:_iframeWidget[1],
        ),
      ),
    ],
    );
    }
    

    【讨论】:

    • 我可以用这个,谢谢。我在“模块”或“部分”中工作,我需要这个“地图”部分和“社交媒体”部分,为此我有 2 个不同的 .dart。我想我必须在同一个空间工作,对吧?我对 Flutter 和 Dart 很陌生。你知道为什么会这样吗?
    • 不,我不知道为什么会这样。但就目前而言,我们只考虑这个,因为 Flutter Web 是 Beta 版。以后会有更多的支持。
    • 嘿,如果您觉得有帮助,请将答案标记为正确
    【解决方案2】:

    这是一个更简洁的 iframe 小部件版本:

    Dartpad example

    //ignore: avoid_web_libraries_in_flutter
    import 'dart:html';
    import 'dart:ui' as ui;
    
    import 'package:flutter/material.dart';
    
    class IframeView extends StatefulWidget {
      final String source;
    
      const IframeView({Key key, @required this.source}) : super(key: key);
    
      @override
      _IframeViewState createState() => _IframeViewState();
    }
    
    class _IframeViewState extends State<IframeView> {
      // Widget _iframeWidget;
      final IFrameElement _iframeElement = IFrameElement();
    
      @override
      void initState() {
        super.initState();
        _iframeElement.src = widget.source;
        _iframeElement.style.border = 'none';
    
        //ignore: undefined_prefixed_name
        ui.platformViewRegistry.registerViewFactory(
          widget.source, //use source as registered key to ensure uniqueness
          (int viewId) => _iframeElement,
        );
      }
    
      @override
      Widget build(BuildContext context) {
        return HtmlElementView(
          key: UniqueKey(),
          viewType: widget.source,
        );
      }
    }
    

    请注意,自从 Dart SDK 中的 this change 以来,抑制 undefined_prefixed_name 错误不再起作用。但是有一个未解决的问题要回复here

    然后,您可以使用大小框内的小部件来限制它的高度/宽度。这是在脚手架主体中使用它的示例:

    //main.dart
    
    import 'package:flutter/material.dart';
    
    void main() async {
      runApp(IFrameTesterApp());
    }
    
    class IFrameTesterApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
              appBar: AppBar(
                title: Text('IFrame Tester App'),
                centerTitle: true,
              ),
              body: IframeView(source: "https://url.to.resource")),
          theme: ThemeData.light(),
        );
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-01-22
      • 2020-07-26
      • 2020-03-09
      • 1970-01-01
      • 2012-11-08
      • 1970-01-01
      • 1970-01-01
      • 2022-06-10
      • 1970-01-01
      相关资源
      最近更新 更多