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 - ListTile Widget
The ListTile widget is used to populate a ListView in Flutter. It contains a title as well as leading or trailing icons. Let's understand this with the help of an example.The Constructor of the ListTile classListTile({ Key key, Widget leading, Widget title, Widget subtitle, Widget trailing, bool isT
4 min read
Table Widget in Flutter
Table widget is used to display items in a table layout. There is no need to use Rows and Columns to create a table. If we have multiple rows with the same width of columns then Table widget is the right approach. SliverList or Column will be most suitable if we only want to have a single column. Th
3 min read
Flutter - Stateful Widget
A Stateful Widget has states in it. To understand a Stateful Widget, you need to have a clear understanding of widgets and state management. A state can be defined as "an imperative changing of the user interface," and a widget is "an immutable description of the part of the user interface". To lear
4 min read
Flutter - OctoImage Widget
The OctoImage widget in Flutter requires an ImageProvider to display images in an application. The images in the OctoImage widget can be supplied with a Progress indicator or a Place holder for loading the Image in it. An OctoImage widget makes use of the Octosets which are nothing but the combinati
4 min read
Flutter - Inherited Widget
If you are a flutter developer then you know how easy is to create Flutter UI. But when you have lots of widgets in your app and you want to pass data from one widget to another widget, this will be a pain for many developers,s especially for the newbie, this will be really hard for them to pass the
6 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. Stepper is generally used in filling forms online. For example, remember filling an online form for applying to any university or passport or driving license. We filled
8 min read
Flutter - TabView Widget
There are lots of apps where you often have come across tabs. Tabs are a common pattern in the apps. They are situated at top of the app below the App bar. So today we are going to create our own app with tabs. Table of Contents:Project SetupCodeConclusionProject Setup: You can either create a new p
4 min read