There are many cases of Android application development where some parts must use HTML as a content source, even some whose entire content is html, this may be possible using WebView, but what if it is only part of it? Okay, let's discuss.
1. HTML tags supported by Android Studio
The Android API documentation has defined what HTML tags they support, so here are the ones that are currently supported.
- b & strong tag for bold
- i, em, cite & dfn tags for Italics
- u tag for Underline
- sub tag for Subtext
- tag soup for Supertext
- big tag for Big
- small tag for Small
- tt tag for Monospace
- h1 to h6 tags for Headlines
- img tag for image
- font tag for Font face and color
- blockquote tag for longer quotes
- a tag for Link
- div and p tags for Paragraph
- br tag for Linefeed
2. How to display HTML content in TextView
Previously, displaying HTML content could use the Html.fromHtml() method, but it was not uncommon to encounter deprecated issues, this occurs in development on SDK targets above 14, let's say you create a minimum target on Android version N (nougat), then you need to use this method HtmlCompat.fromHtml().
There are 4 variants of using the fromHtml() method, and it lies in the parameters used.
- fromHtml(String source), this method is used to display text style as created by CSS. Note, this method is deprecated for API 24 and above, please use fromHtml(String, int) instead.
- fromHtml(String source, int flags), this method replaces the previous method, as I mentioned earlier, so we need one more parameter of type integer, but we cannot just input it because to be able to work properly we just need to choose the flags that have been provided by the Android API, for example we choose the FROM_HTML_MODE_LEGACY flag.
- fromHtml(String source, Html.ImageGetter imageGetter, Html.TagHandler tagHandler) This method is used to display text style, image tag, so we need to specifically use the ImageGetter parameter to request to the internet, but if you don't want it, then just make this parameter null. Meanwhile, TagHandler is to handle unknown tags, again if you don't want it, please just make it null.
- fromHtml(String source, int flags, Html.ImageGetter imageGetter, Html.TagHandler tagHandler), this method is used to replace the previous method, which will be obsolete for the target API above, this method needs to include the FROM_HTML_MODE_LEGACY flag.
Some constant flags that can be used for parsing HTML content.
- FROM_HTML_MODE_COMPACT, this flag is used to separate block level elements with single line breaks / new lines / br tags.
- FROM_HTML_MODE_LEGACY, this flag is used to separate block level elements with blank lines (meaning double break lines).
- FROM_HTML_OPTION_USE_CSS_COLORS, this flag is used to prioritize color definitions in the HTML content css over color definitions in the textView.
- FROM_HTML_SEPARATOR_LINE_BREAK_BLOCKQUOTE, this flag is used to indicate that the text between the < blockquote > tags will be separated from other text by the distance of each single line break either before or after it.
- FROM_HTML_SEPARATOR_LINE_BREAK_DIV, this flag indicates that the text between the <div> tags will be separated from other text by the distance of each single line break either before or after it.
- FROM_HTML_SEPARATOR_LINE_BREAK_HEADING, this flag indicates that the text between the tags < h1 >, < h2 >, < h3 >, < h4 >, < h5 > and < h6 > will be separated from the rest of the text by the distance of each single line break either before or after it.
- FROM_HTML_SEPARATOR_LINE_BREAK_LIST, this flag indicates that the text between the <ul> tags will be separated from other text by the distance of each single line break either before or after it.
- FROM_HTML_SEPARATOR_LINE_BREAK_LIST_ITEM, this flag indicates that the text between the < li > tags will be separated from other text by the distance of each single line break either before or after it.
- FROM_HTML_SEPARATOR_LINE_BREAK_PARAGRAPH, this flag indicates that the text between the < p > tags will be separated from other text by the distance of each single line break either before or after it.
Here we provide an example of how to work with TextView to display HTML content. First we create a new project, specifically for practice please name it HtmlExample. Don't forget to select Empty Activity for initialization when the project is generated.
Next, modify the activity_main.xml layout as follows.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="abhiandroid.com.htmlexample.MainActivity">
<TextView
android:id="@+id/simpleTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp" />
</RelativeLayout>
Next, pay attention to the code below, I initialize the content variable with a string type to hold HTML content, this is what I mean by some content using html. Okay, now please overhaul MainActivity.java so that it is like this.
import android.os.Build;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Html;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
TextView textView;
String content="<h1>Heading 1</h1>\n" +
" <h2>Heading 2</h2>\n" +
" <p>This is some html. Look, here\\'s an <u>underline</u>.</p>\n" +
" <p>Look, this is <em>emphasized.</em> And here\\'s some <b>bold</b>.</p>\n" +
" <p>Here are UL list items:\n" +
" <ul>\n" +
" <li>One</li>\n" +
" <li>Two</li>\n" +
" <li>Three</li>\n" +
" </ul>\n" +
" <p>Here are OL list items:\n" +
" <ol>\n" +
" <li>One</li>\n" +
" <li>Two</li>\n" +
" <li>Three</li>\n" +
" </ol>";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// init TextView
textView = (TextView) findViewById(R.id.simpleTextView);
// set Text in TextView using fromHtml() method with version check
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
textView.setText(Html.fromHtml(content, Html.FROM_HTML_MODE_LEGACY));
} else
textView.setText(Html.fromHtml(content));
}
}
Now, run the project to see the results shown by the TextView.
3. How to display HTML content in WebView
Well, before we go any further, it would be better if I first give a simple description of the case study that we will face, the goal is so that my friends are not confused about which method to use when faced with a similar case at work later.
Ok, let's say we have pages A, B, and C. The content of page A comes from a specific web page, let's say from " https://bundet.com/pub/detail/cara-parsing-html-menggunakan-textview-dan-webview-di-android-studio-1579187824 ". While the content of page B is local, let's say from your project in the assets/yourfile.html folder. Finally page C only needs some html content.
Okay, to deal with the case of pages A and B we can use the loadUrl() method, while for page C we can use loadDataWithBaseURL(). Do you understand so far? So, I only need to give 2 examples of the work, because the handling of pages A & B is basically the same.
a. Handle pages A & B using loadUrl()
Still in the same project, please prepare some buttons to switch to different pages with different cases or if you are still confused, please create a new project again and name it "Latihan WebView loadUrl", as usual select Empty Activity for initialization when the project is generated.
Next, modify the activity_main.xml layout to look like this.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="abhiandroid.com.htmlexample.MainActivity">
<WebView
android:id="@+id/simpleWebView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp" />
</RelativeLayout>
Next, create an assets folder in your project folder, and create a file with the extension *html, say "myfile.html", then adjust the contents as below.
<h1>Heading 1</h1>
<h2>Heading 2</h2>
<p>This is some html. Look, here's an <u>underline</u>.</p>
<p>Look, this is <em>emphasized.</em> And here\\'s some <b>bold</b>.</p>
<p>Here are UL list items:
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
<p>Here are OL list items:
<ol>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ol>
Next, overhaul MainActivity.java so that it is such.
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.webkit.WebView;
public class MainActivity extends AppCompatActivity {
WebView webView;
public String fileName = "myfile.html";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// init webView
webView = (WebView) findViewById(R.id.simpleWebView);
// displaying content in WebView from html file that stored in assets folder
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl("file:///android_asset/" + fileName);
}
}
Run the project to see the results.
b. Handle page C using loadDataWithBaseURL()
Please feel free to create another project, or for those who already understand, you can create a new activity. The principle is that we prepare a special activity for each different case.
OK, as usual, change the activity_main.xml layout so that it looks like this.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="abhiandroid.com.htmlexample.MainActivity">
<WebView
android:id="@+id/simpleWebView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp" />
</RelativeLayout>
Don't forget to also overhaul MainActivity.java so that it is in such a way.
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.webkit.WebView;
public class MainActivity extends AppCompatActivity {
WebView webView;
String content="<h1>Heading 1</h1>\n" +
" <h2>Heading 2</h2>\n" +
" <p>This is some html. Look, here\\'s an <u>underline</u>.</p>\n" +
" <p>Look, this is <em>emphasized.</em> And here\\'s some <b>bold</b>.</p>\n" +
" <p>Here are UL list items:\n" +
" <ul>\n" +
" <li>One</li>\n" +
" <li>Two</li>\n" +
" <li>Three</li>\n" +
" </ul>\n" +
" <p>Here are OL list items:\n" +
" <ol>\n" +
" <li>One</li>\n" +
" <li>Two</li>\n" +
" <li>Three</li>\n" +
" </ol>";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// init webView
webView = (WebView) findViewById(R.id.simpleWebView);
// displaying text in WebView
webView.loadDataWithBaseURL(null, content, "text/html", "utf-8", null);
}
}
Run the project and see the results.
That's our review of HTML parsing in Android Studio, hopefully it's useful!