更改堆栈中 PlatformViews (iFrame) 的顺序会导致渲染失败
Changing the order of PlatformViews (iFrame) in a Stack causes the render to fail
一个可能的解决方法是避免在 Positioned 小部件 (L: 42) 中使用键,但这会导致 HtmlElementView(或其他显示的项目,如视频)的内部状态重置为实际状态处置。
在下面的示例中,平台工厂的用法可能实现错误,或者密钥不应该这样使用。但是,我怀疑这与 DOM & Flutter 的 SDK 有关。
import 'dart:html' as html;
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) => const MaterialApp(home: MyHomePage());
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<int> order = [
1,
2,
];
void _reverseOrder() {
setState(() {
order = order.reversed.toList();
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Test'),
),
body: Stack(
children: order
.map<Widget>((o) => Positioned(
key: Key(o.toString() + o.toString()),
/*
key is used
*/
left: o * 100,
top: o * 100,
width: o * 250,
height: o * 250,
child: Stack(
children: [
child(o),
Center(child: Text(o.toString())),
],
),
))
.toList()),
floatingActionButton: FloatingActionButton(
onPressed: _reverseOrder,
tooltip: 'Reverse order of widgets',
child: const Icon(Icons.refresh),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
Widget child(int id) {
return createIFrame(
'sample.pdf',
id.toString(),
);
// // Works without issues with non platform widgets
// return Container(
// color: Color.fromARGB(255, 100 * id, 100 * id, 100 * id),
// );
}
Widget createIFrame(
String url,
String id,
) {
ui.platformViewRegistry.registerViewFactory(
id,
(int viewId) => html.IFrameElement()..src = url,
);
return HtmlElementView(viewType: id);
}
有用的链接:
platform-views-using-html-slots-web
这实际上是 SDK 中的一个问题。
在引起他们的注意后,它被 flutter 团队修复了。
一个可能的解决方法是避免在 Positioned 小部件 (L: 42) 中使用键,但这会导致 HtmlElementView(或其他显示的项目,如视频)的内部状态重置为实际状态处置。
在下面的示例中,平台工厂的用法可能实现错误,或者密钥不应该这样使用。但是,我怀疑这与 DOM & Flutter 的 SDK 有关。
import 'dart:html' as html;
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) => const MaterialApp(home: MyHomePage());
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<int> order = [
1,
2,
];
void _reverseOrder() {
setState(() {
order = order.reversed.toList();
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Test'),
),
body: Stack(
children: order
.map<Widget>((o) => Positioned(
key: Key(o.toString() + o.toString()),
/*
key is used
*/
left: o * 100,
top: o * 100,
width: o * 250,
height: o * 250,
child: Stack(
children: [
child(o),
Center(child: Text(o.toString())),
],
),
))
.toList()),
floatingActionButton: FloatingActionButton(
onPressed: _reverseOrder,
tooltip: 'Reverse order of widgets',
child: const Icon(Icons.refresh),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
Widget child(int id) {
return createIFrame(
'sample.pdf',
id.toString(),
);
// // Works without issues with non platform widgets
// return Container(
// color: Color.fromARGB(255, 100 * id, 100 * id, 100 * id),
// );
}
Widget createIFrame(
String url,
String id,
) {
ui.platformViewRegistry.registerViewFactory(
id,
(int viewId) => html.IFrameElement()..src = url,
);
return HtmlElementView(viewType: id);
}
有用的链接:
platform-views-using-html-slots-web
这实际上是 SDK 中的一个问题。 在引起他们的注意后,它被 flutter 团队修复了。