Tutorial: Using WebView to load the html page from Assets

Wow, it’s been a long time since my last post!

Today I would like to talk about the WebViewAndroid‘s view for displaying web pages. The first thing to know is that it has a few methods to load data and sometimes it may not be so obvious which one to use. So, we will go step by step on how to load the html page, which is located in project’s assets directory. It won’t be just a simple text: custom font, an image and some style will be applied to this page as well.

OK, so let’s begin!

First, I have created an empty Android project (I used Intellij Idea 11 as my IDE, but it really doesn’t matter which IDE to use in this tutorial). The package name for this tutorial is –com.lomza.tut.webview. Then add two new folders to the assets folder: fonts and images. The first one will contain our custom font and the second one will be used as a resource directory for images. I have used an English Essay font – it’s a beautiful calligraphy font, free for non-commercial use. You can download it from here. Copy the .ttf file into the fonts directory. Then save the butterfly_image.jpg picture, and place it into the images directory.

butterfly

OK, now it’s time for the .html page! Create a new .html file in assets directory and name it butterfly_html_page.html. You can see the content of my butterfly_html_page below:

<meta http-equiv="content-type" content="text/html;charset=UTF-8"/>
<html>
<head>
<title>Butterfly</title>
<style type="text/css">
    @font-face {
        font-family: MyFont;
        src: url("file:///android_asset/fonts/english_essay.ttf");
    }

    body {
        font-family: MyFont;
        color: #2F4F2F;
        font-style: italic;
    }

    img {
        float: left;
        border: solid 5pt #2F4F2F;
        margin: 0pt 5pt 5pt 5pt;
    }
</style>
</head>
<body>
    <h2>Do you want to know more about butterflies?</h2>
    <img src="butterfly_image.jpg" alt="Beautiful butterfly :)" />
    <p>
    A butterfly is a mainly day-flying insect of the order Lepidoptera, which includes the butterflies and moths.
    Like other holometabolous insects, the butterfly's life cycle consists of four parts: egg, larva, pupa and adult.
    Most species are diurnal. Butterflies have large, often brightly coloured wings, and conspicuous, fluttering flight.
    Butterflies comprise the true butterflies (superfamily Papilionoidea),
    the skippers (superfamily Hesperioidea) and the moth-butterflies (superfamily Hedyloidea).
    </p>
    <p>
    Butterflies exhibit polymorphism, mimicry and aposematism.
    Some, like the Monarch, will migrate over long distances.
    Some butterflies have evolved symbiotic and parasitic relationships with social insects such as ants.
    Some species are pests because in their larval stages they can damage domestic crops or trees; however,
    some species are agents of pollination of some plants, and caterpillars of a few butterflies (e.g., Harvesters)
    eat harmful insects.
    Culturally, butterflies are a popular motif in the visual and literary arts.
    </p>
    <p>
        Wikipedia
    </p>
</body>
</html>

There is a meta data on the top. This is not required, but I prefer everything to be clear, the content type and the charset. Between the head tags there is a title of the page and a few styles. The first one declares a font for the text. I used a MyFont font-family, but you can name it whatever you want, maybe something more reasonable 🙂

Then I have a default color of the text and it’s style, which is italic. For image I have used left float property, which will position our image on the left side and the text will nicely wrap it. The border is 5pt thick, same color as text and there is a 5pt border on right, bottom and left of the image as well.

The body contains a header, image and a few paragraphs of text. Please pay attention to the font and image’s url. The url for our font is absolute, and the url for the image is local. Why is that? Because we will use the absolute url for images as the base URL for our html page. It means, if we had more images on our html page, their URLs would’ve look like this: image_name.jpg, image_name.png and so on. No need for a full path. Quite convenient, huh?

Now that we have our assets, it’s time for the layout. There will just a LinearLayout and a WebView inside the default main layout.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:orientation="vertical"
         android:layout_width="match_parent"
         android:layout_height="match_parent">

<WebView android:id="@+id/butterfly_webview"
        android:layout_height="match_parent"
        android:layout_width="wrap_content" />
</LinearLayout>

I use a match_parent instead of the deprecated fill_parent as the project target is API 8. I see no point in supporting Android API lower than 8.

OK, now only the Java code left!

Create & rename our single Activity to MainActivity and add it to the AndroidManifest.xml file. Set a content view to R.layout.main. Declare and define the mButterflyWebView. Add the init() method call to the onCreate() method. Like this:


    private WebView mButterflyWebView;

    /**
     * Initializes views, controls...
     */
    private void init() {
        mButterflyWebView = (WebView) findViewById(R.id.butterfly_webview);
    }

    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        init();
    }

Now we need to load our html page with all its resources. And the WebView has a multiple methods for loading data: loadData(), loadDataWithBaseURL(), and a loadURL() (you can read about them here). The first one I don’t recommend to use, as it has a few restriction. Although, there is an encoding parameter, it is only used for specifying whether the text is base64 or URL encoded. If you want to use UTF-8 or any encoding other than ASCII, use loadDataWithBaseURL() method. Finally, loadURL() method is used for loading the given URL with or without additional headers supplied.

The best and the most “flexible” method for us would be the loadDataWithBaseURL(). But first we need to get the html string from the butterfly_html_page.html. To do that create a method getHtmlFromAsset(). Copy and paste the code below:


    /**
     * Gets html content from the assets folder.
     */
    private String getHtmlFromAsset() {
        InputStream is;
        StringBuilder builder = new StringBuilder();
        String htmlString = null;
        try {
            is = getAssets().open(getString(R.string.butterfly_html));
            if (is != null) {
                BufferedReader reader = new BufferedReader(new InputStreamReader(is));
                String line;
                while ((line = reader.readLine()) != null) {
                    builder.append(line);
                }

                htmlString = builder.toString();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return htmlString;
    }

We just get a file as the InputStream. Then read it with a BufferedReader and append to our StringBuilder. At the end, just return the String representation of a StringBuilder. The R.string.butterfly_html is just a name of our html file. I’ve putted it to strings.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">WebViewLoadDataTutorial</string>
    <string name="butterfly_html">butterfly_html_page.html</string>
    <string name="no_such_page">There is no such page&#8230;</string>
</resources>

The big plus of this approach is that as we have an html String which can be formated, appended to something, changed in so many ways!

OK, now it’s time for the actual loading of the html file!

Create a method loadHtmlPage() and copy&paste the code inside:


    /**
     * Loads html page with the content.
     */
    private void loadHtmlPage() {
        String htmlString = getHtmlFromAsset();
        if (htmlString != null)
            mButterflyWebView.loadDataWithBaseURL("file:///android_asset/images/", htmlString, "text/html", "UTF-8", null);

        else
            Toast.makeText(this, R.string.no_such_page, Toast.LENGTH_LONG).show();
    }

First, we get a html string, than pass it to the loadDataWithBaseURL() method as a data parameter. The BASE URL is file:///android_asset/images/, which basically says “load the needed resources from this directory”, MIME type is text/html, the encoding is UTF-8 and the history URL is null. The last one is used when user navigates from one web page to another and you want to specify what would be the default web page. Leaving it empty/null will be equal to about:blank which will result in white page. We don’t have any navigation, so just put null.

And this is it! Now you can run the app and see the results!

butterfly

Like and share:

Published by

Tonia Tkachuk

I'm an Android Developer, writing code for living and for fun. Love beautiful apps with a clean code inside. Enjoy travelling and reading.