Flutter is growing with its libraries and community. Earlier, we could use Machine Learning and Flutter together to create powerful applications. Now, we can combine Flutter and HTML too. If there is a static HTML webpage that we want to render in our application that is built using Flutter. With this flutter_html Flutter package, we can render the entire webpage in the Flutter application.
HTML and Flutter are different, if we want to render an HTML page with CSS in Flutter, it seems weird. This means how is it possible that HTML code will render on-screen using Flutter. Well, it sounds difficult but until flutter_html package in Flutter was not published. In this article, we will learn about the working of this Flutter library by creating a sample app.
Implementation:
Step 1: To commence with, create a Flutter Project.
Step 2: Add dependency
In the pubspec.yaml file add the flutter_html package inside the dependencies section.
To install it run pub get in the terminal of IDE or simply press CTRL+S in Windows to add it.
Step 3: Import Dependency.
In the main.dart file, import dependency as -
Dart
import 'package:flutter_html/flutter_html.dart';
Step 4: Get the HTML page.
Now, get the HTML page that we want to display on the screen in Flutter. For Example, we are taking an HTML sample code:
HTML
const htmlData = r"""
<p id='top'><a href='#'>This is the link</a></p>
<h1>Header 1</h1>
<h2>Header 2</h2>
<h3>Header 3</h3>
<h4>Header 4</h4>
<h5>Header 5</h5>
<h6>Header 6</h6>
<h3>This is HTML page that we want to integrate with Flutter.</h3>
""";
We cannot assign htmlData to the Text widget, we have to use the flutter_html package to render this htmlData on the app.
Step 5: Use HTML() widget and assign values to its properties. We will assign htmlData to its data property, and all the Html tags to the tagsList.
Dart
Html(
data: htmlData,
tagsList: Html.tags,
style: {
"table": Style(
backgroundColor: Color.fromARGB(0x50, 0xee, 0xee, 0xee),
),
"tr": Style(
border: Border(bottom: BorderSide(color: Colors.grey)),
),
"th": Style(
padding: EdgeInsets.all(6),
backgroundColor: Colors.grey,
),
"td": Style(
padding: EdgeInsets.all(6),
alignment: Alignment.topLeft,
),
'h5': Style(maxLines: 2, textOverflow: TextOverflow.ellipsis),
},
),
Source Code:
Dart
import 'package:flutter/material.dart';
import 'package:flutter_html/flutter_html.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.green,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => new _MyHomePageState();
}
const htmlData = r"""
<p id='top'><a href='#'>This is the Link</a></p>
<h1>Header 1</h1>
<h2>Header 2</h2>
<h3>Header 3</h3>
<h4>Header 4</h4>
<h5>Header 5</h5>
<h6>Header 6</h6>
<h3>This is HTML page that we want to integrate with Flutter.</h3>
""";
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: Text('GeeksForGeeks'),
centerTitle: true,
),
body: SingleChildScrollView(
child: Html(
data: htmlData,
tagsList: Html.tags,
style: {
"table": Style(
backgroundColor: Color.fromARGB(0x50, 0xee, 0xee, 0xee),
),
"tr": Style(
border: Border(bottom: BorderSide(color: Colors.grey)),
),
"th": Style(
padding: EdgeInsets.all(6),
backgroundColor: Colors.grey,
),
"td": Style(
padding: EdgeInsets.all(6),
alignment: Alignment.topLeft,
),
'h5': Style(maxLines: 2, textOverflow: TextOverflow.ellipsis),
},
),
),
);
}
}
Output:
Step 6: We can create custom tags and then add them to the HTML tags list using tagList property tagList: HTML.tags..add(‘flutter’). Like here we are creating a custom ‘flutter’ tag and adding it to the HTML tags list. For Example: <flutter></flutter>
We need to assign the HTML data to the data property of the HTML() widget.
Every HTML tag whether it is a table tag or ordered list tag all are supported along with the customized tags functionality. Also in HTML() widget style property, we can give styles to the HTML tags and custom tags. We can also add styling to images being rendered from networks and domains. For a better understanding see the below code.
Source Code:
Dart
void main() {
import 'package:flutter/material.dart';
import 'package:flutter_html/flutter_html.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return new MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Tutorial',
theme: new ThemeData(
primarySwatch: Colors.green,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => new _MyHomePageState();
}
const htmlData = r"""
<body style="background-color:powderblue;">
<h3>Support for math equations:</h3>
Solve for <var>x<sub>n</sub></var>: log<sub>2</sub>(<var>x</var><sup>2</sup>+<var>n</var>) = 9<sup>3</sup>
<h3>Inline Styles:</h3>
<p>This should be <span style='color: blue;'>BLUE style='color: blue;'</span></p>
<h3>Table support (with custom styling!):</h3>
<table>
<colgroup>
<col width="50%" />
<col span="2" width="25%" />
</colgroup>
<thead>
<tr><th>One</th><th>Two</th><th>Three</th></tr>
</thead>
<tbody>
<tr>
<td rowspan='2'>Rowspan</td><td>Data</td><td>Data</td>
</tr>
<tr>
<td colspan="2"><img alt='Google' src='https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_92x30dp.png' /></td>
</tr>
</tbody>
<tfoot>
<tr><td>fData</td><td>fData</td><td>fData</td></tr>
</tfoot>
</table>
<h4>Below is the custom tag: Flutter tag</h4>
<flutter vertical></flutter>
<h3>List support:</h3>
<ol>
<li>This</li>
<li>
<p>is</p>
</li>
<li>
ordered
<ul>
<li>This is a</li>
<li>nested</li>
<li>unordered list
</li>
</ul>
</li>
</ol>
<h3>Images are also supported:</h3>
<h3>Network png</h3>
<img src="https://res.cloudinary.com/nitishk72/image/upload/v1586796259/nstack_in/courses/flutter/flutter-banner.png">
<h3>Network svg</h3>
<img src='https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/android.svg' />
<h3>Data uri (with base64 support)</h3>
<img alt='Red dot (png)' src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==' />
<img alt='Green dot (base64 svg)' src='data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB2aWV3Qm94PSIwIDAgMzAgMjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxjaXJjbGUgY3g9IjE1IiBjeT0iMTAiIHI9IjEwIiBmaWxsPSJncmVlbiIvPgo8L3N2Zz4=' />
<img alt='Green dot (plain svg)' src='data:image/svg+xml,%3C?xml version="1.0" encoding="UTF-8"?%3E%3Csvg viewBox="0 0 30 20" xmlns="http://www.w3.org/2000/svg"%3E%3Ccircle cx="15" cy="10" r="10" fill="yellow"/%3E%3C/svg%3E' />
""";
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: Text('GeeksForGeeks'),
centerTitle: true,
),
body: SingleChildScrollView(
child: Html(
data: htmlData,
tagsList: Html.tags..add("flutter"),
style: {
// add style to the tags in HTML code
"table": Style(
backgroundColor: Color.fromARGB(0x50, 0xee, 0xee, 0xee),
),
"tr": Style(
border: Border(bottom: BorderSide(color: Colors.grey)),
),
"th": Style(
padding: EdgeInsets.all(6),
backgroundColor: Colors.grey,
),
"td": Style(
padding: EdgeInsets.all(6),
alignment: Alignment.topLeft,
),
'h5': Style(maxLines: 2, textOverflow: TextOverflow.ellipsis),
},
customRender: {
"table": (context, child) {
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: (context.tree as TableLayoutElement).toWidget(context),
);
},
// adding customizable tag
"flutter": (RenderContext context, Widget child) {
// giving style to Flutter tag with FlutterLogo() widget
return FlutterLogo(
style: (context.tree.element!.attributes['horizontal'] != null)
? FlutterLogoStyle.horizontal
: FlutterLogoStyle.markOnly,
textColor: context.style.color!,
size: context.style.fontSize!.size! * 5,
);
},
},
customImageRenders: {
// We can give similar features to elements
// from the same domain like for flutter.dev
// We can define any number of networkSourceMatcher
networkSourceMatcher(domains: ["flutter.dev"]):
(context, attributes, element) {
return FlutterLogo(size: 36);
},
networkSourceMatcher(domains: ["mydomain.com"]): networkImageRender(
headers: {"Custom-Header": "some-value"},
altWidget: (alt) => Text(alt ?? ""),
loadingWidget: () => Text("Loading..."),
),
// If relative paths starts with /wiki,
// prefix them with a base url
(attr, _) =>
attr["src"] != null && attr["src"]!.startsWith("/wiki"):
networkImageRender(
mapUrl: (url) => "https://upload.wikimedia.org" + url!),
// If links for images are broken use Custom placeholder
// image
networkSourceMatcher():
networkImageRender(altWidget: (_) => FlutterLogo()),
},
onCssParseError: (css, messages) {
//If error occurs while applying CSS to HTML
print("css that errored: $css");
print("error messages:");
messages.forEach((element) {
print(element);
});
},
),
),
);
}
}
Output:
Similar Reads
Flutter - Stack Widget The Stack widget in Flutter is a powerful tool that allows for the layering of multiple widgets on top of each other. While layouts like Row and Column arrange widgets horizontally and vertically, respectively, Stack provides a solution when you need to overlay widgets. For instance, if you want to
6 min read
Flutter - RichText Widget The RichText widget is used to display text that uses various different styles. The displayed text is described using a tree of TextSpan objects, each of which has its own associated style that is used for that subtree. Depending on the layout constraints the text might break across multiple lines o
3 min read
Flutter - StreamBuilder Widget A StreamBuilder in Flutter is used to listen to a stream of data and rebuild its widget subtree whenever new data is emitted by the stream. It's commonly used for real-time updates, such as when working with streams of data from network requests, databases, or other asynchronous sources. In this art
5 min read
Flutter - Stepper Widget In this article, we will learn about the Stepper widget in Flutter. A stepper widget displays progress through a sequence of steps. A stepper is generally used in filling out forms online.For example, remember filling out an online form for applying to any university or passport, or driving license.
6 min read
What is Widgets in Flutter? Flutter is Google's UI toolkit for crafting beautiful, natively compiled iOS and Android apps from a single code base. To build any application we start with widgets - The building block of Flutter applications. Widgets describe what their view should look like given their current configuration and
5 min read
Flutter - Themes Themes are an integral part of UI for any application. Themes are used to design the fonts and colors of an application to make it more presentable. In Flutter, the Theme widget is used to add themes to an application. One can use it either for a particular part of the application like buttons and n
3 min read