3

I'm new in Flutter and i'm developing a little web page for learn. I wanna put a google map and facebook feed using two iframe.

I base my code on Wangoo's code here: https://medium.com/flutter-community/flutter-web-and-iframe-f26399aa1e2a

If i use only one iframe it works perfect but if i use a second one it has the first's source and the first one doesn't show anything. Like this: https://i.stack.imgur.com/irTyY.jpg

Already test some others packages but the most isn't web compatible or just can't use an iframe with link like those ones

This is my code:

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,
    );
  }
}

Thanks :)

Junsu Cho
  • 826
  • 7
  • 16
MasterNOD
  • 31
  • 1
  • 5

2 Answers2

9

Here is a much cleaner version of an iframe widget:

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,
    );
  }
}

Note that suppressing the undefined_prefixed_name error no longer works since this change in the Dart SDK. But there is an open issue to revert here.

You can then use the widget inside of a sized box to constrain it's height/width. Here is example of using it within scaffold body:

//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(),
    );
  }
}
jnt
  • 1,133
  • 14
  • 10
4

Yes, you can use Two Iframes in the Flutter web.

But it won't work if you do it like that. Instead, In my code, I pass the links.

Just Use two IframeWidget with different viewIDs'. Here I used it to get my Social media Project on my Website.

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],
    ),
  ),
],
);
}
DIVYANSHU SAHU
  • 1,035
  • 11
  • 24
  • I can work with this, thanks. I'm working like in "modules" or "sections" and i need this "Map" section and "Social media" section, i have 2 different .dart for this. I suppose i must work on the same space for this right? I'm pretty new on Flutter and Dart. Do u know why this happen? – MasterNOD Aug 14 '20 at 08:35
  • No, I don't why this happen. But for now, let's go with this only as the flutter web is Beta. Later on, It will have more support. – DIVYANSHU SAHU Aug 14 '20 at 11:55
  • hey, If you find that helpful please mark the answer as right – DIVYANSHU SAHU Sep 23 '20 at 07:05