Skip to content

Commit f98bb5e

Browse files
authored
Update README.md
1 parent 24fda6b commit f98bb5e

File tree

1 file changed

+65
-99
lines changed

1 file changed

+65
-99
lines changed

README.md

Lines changed: 65 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -225,104 +225,65 @@ Packages used: [`data_connection_checker`](https://pub.dev/packages/data_connect
225225
<details><summary>View code</summary>
226226

227227
```dart
228-
class CustomRenderExample extends StatefulWidget {
229-
CustomRenderExample({Key key, this.title}) : super(key: key);
230-
231-
final String title;
232-
233-
@override
234-
CustomRenderExampleState createState() => new CustomRenderExampleState();
235-
}
236-
237-
class CustomRenderExampleState extends State<CustomRenderExample> {
238-
bool result = false;
239-
240-
@override
241-
void initState() async {
242-
// store current internet connection status
243-
result = await DataConnectionChecker().hasConnection;
244-
super.initState();
245-
}
246-
247-
@override
248-
Widget build(BuildContext context) {
249-
return new Scaffold(
250-
appBar: AppBar(
251-
title: Text('flutter_html Example'),
252-
centerTitle: true,
253-
),
254-
body: SingleChildScrollView(
255-
child: Html(
256-
data: """
257-
<h3>YouTube iframe:</h3>
258-
<iframe src="https://google.com"></iframe>
259-
<h3>Google iframe:</h3>
260-
<iframe src="https://www.youtube.com/embed/tgbNymZ7vqY"></iframe>
261-
""",
262-
customRender: {
263-
"iframe": (RenderContext context, Widget child, Map<String, String> attributes, _) {
264-
// check internet connection
265-
if (!result) {
266-
return Container(
267-
child: ListTile(
268-
leading: Icon(Icons.error, color: Colors.red),
269-
title: Text("Cannot load iframe. You are offline, please check connection and try again.")
270-
)
271-
);
272-
} else if (attributes != null) {
273-
double width = double.tryParse(attributes['width'] ?? "");
274-
double height = double.tryParse(attributes['height'] ?? "");
275-
print(attributes['src']);
276-
return Container(
277-
width: width ?? (height ?? 150) * 2,
278-
height: height ?? (width ?? 300) / 2,
279-
child: InAppWebView(
280-
initialUrl: attributes['src'],
281-
// recommended options when using this implementation
282-
initialOptions: InAppWebViewGroupOptions(
283-
crossPlatform: InAppWebViewOptions(
284-
javaScriptEnabled: true,
285-
cacheEnabled: false,
286-
disableVerticalScroll: attributes['src'].contains("youtube.com/embed") ? true : false,
287-
disableHorizontalScroll: attributes['src'].contains("youtube.com/embed") ? true : false,
288-
useShouldOverrideUrlLoading: true,
289-
),
290-
ios: IOSInAppWebViewOptions(
291-
allowsLinkPreview: false,
292-
),
293-
android: AndroidInAppWebViewOptions(
294-
useHybridComposition: true,
295-
)
296-
),
297-
// no need for a scrolling gesture recognizer for embedded youtube videos so we only use VerticalDragGestureRecognizer when the iframe does not display embedded youtube videos
298-
gestureRecognizers: attributes['src'].contains("youtube.com/embed") ? null : [
299-
Factory(() => VerticalDragGestureRecognizer())
300-
].toSet(),
301-
// no need to load other urls when displaying embedded youtube videos so we block url loading requests when this is the case
302-
shouldOverrideUrlLoading: (controller, request) async {
303-
if (attributes['src'].contains("youtube.com/embed")) {
304-
if (!request.url.contains("youtube.com/embed")) {
305-
return ShouldOverrideUrlLoadingAction.CANCEL;
306-
} else {
307-
return ShouldOverrideUrlLoadingAction.ALLOW;
308-
}
309-
} else {
310-
return ShouldOverrideUrlLoadingAction.ALLOW;
311-
}
312-
},
313-
),
314-
);
315-
// if the src of the iframe is null then do not render anything
228+
Widget html = Html(
229+
data: """
230+
<h3>Google iframe:</h3>
231+
<iframe src="https://google.com"></iframe>
232+
<h3>YouTube iframe:</h3>
233+
<iframe src="https://www.youtube.com/embed/tgbNymZ7vqY"></iframe>
234+
""",
235+
customRender: {
236+
"iframe": (RenderContext context, Widget child, Map<String, String> attributes, _) {
237+
if (attributes != null) {
238+
double width = double.tryParse(attributes['width'] ?? "");
239+
double height = double.tryParse(attributes['height'] ?? "");
240+
print(attributes['src']);
241+
return Container(
242+
width: width ?? (height ?? 150) * 2,
243+
height: height ?? (width ?? 300) / 2,
244+
child: InAppWebView(
245+
initialUrl: attributes['src'],
246+
// recommended options when using this implementation
247+
initialOptions: InAppWebViewGroupOptions(
248+
crossPlatform: InAppWebViewOptions(
249+
javaScriptEnabled: true,
250+
cacheEnabled: false,
251+
disableVerticalScroll: attributes['src'].contains("youtube.com/embed") ? true : false,
252+
disableHorizontalScroll: attributes['src'].contains("youtube.com/embed") ? true : false,
253+
useShouldOverrideUrlLoading: true,
254+
),
255+
ios: IOSInAppWebViewOptions(
256+
allowsLinkPreview: false,
257+
),
258+
android: AndroidInAppWebViewOptions(
259+
useHybridComposition: true,
260+
)
261+
),
262+
// no need for a scrolling gesture recognizer for embedded youtube videos so we only use VerticalDragGestureRecognizer when the iframe does not display embedded youtube videos
263+
gestureRecognizers: attributes['src'].contains("youtube.com/embed") ? null : [
264+
Factory(() => VerticalDragGestureRecognizer())
265+
].toSet(),
266+
// no need to load other urls when displaying embedded youtube videos so we block url loading requests when this is the case
267+
shouldOverrideUrlLoading: (controller, request) async {
268+
if (attributes['src'].contains("youtube.com/embed")) {
269+
if (!request.url.contains("youtube.com/embed")) {
270+
return ShouldOverrideUrlLoadingAction.CANCEL;
316271
} else {
317-
return Container(height: 0);
272+
return ShouldOverrideUrlLoadingAction.ALLOW;
318273
}
274+
} else {
275+
return ShouldOverrideUrlLoadingAction.ALLOW;
319276
}
320-
}
321-
),
322-
),
323-
);
324-
}
325-
}
277+
},
278+
),
279+
);
280+
// if the src of the iframe is null then do not render anything
281+
} else {
282+
return Container(height: 0);
283+
}
284+
}
285+
}
286+
),
326287
```
327288
</details>
328289

@@ -363,12 +324,17 @@ Widget html = Html(
363324
A list of elements the `Html` widget should not render. The list should contain the tags of the HTML elements you wish to blacklist.
364325

365326
#### Example Usage - blacklistedElements:
366-
`h1` will render, but `h2` will not render
327+
You may have instances where you can choose between two different types of HTML tags to display the same content. In the example below, the `<video>` and `<iframe>` elements are going to display the same content.
328+
329+
The `blacklistedElements` parameter allows you to change which element is rendered. Iframes can be advantageous because they allow parallel loading - Flutter just has to wait for the webview to be initialized before rendering the page, possibly cutting down on load time. Video can be advantageous because it provides a 100% native experience with Flutter widgets, but it may take more time to render the page. You may know that Flutter webview is a little janky in its current state on Android, so using `blacklistedElements` and a simple condition, you can get the best of both worlds - choose the video widget to render on Android and the iframe webview to render on iOS.
367330
```dart
368331
Widget html = Html(
369-
data: """<h1>Header 1</h1>
370-
<h2>Header 2</h2>""",
371-
blacklistedElements: [h2]
332+
data: """
333+
<video controls>
334+
<source src="https://www.w3schools.com/html/mov_bbb.mp4" />
335+
</video>
336+
<iframe src="https://www.w3schools.com/html/mov_bbb.mp4"></iframe>""",
337+
blacklistedElements: [Platform.isAndroid ? "iframe" : "video"]
372338
);
373339
```
374340

0 commit comments

Comments
 (0)