Use custom font from res/font with WebView in Android

1daemon1 picture 1daemon1 · Sep 21, 2017 · Viewed 8.3k times · Source

I want to change font face of html string loaded into WebView similarly as mentioned in this question:

How to change font face of Webview in Android?

The difference is that I am not using old approach where you store you font files in assets folder, but I store them in res/font as described in "Fonts in XML" android font support documentation:

https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml.html

Now, I obviously can't use:

file:///android_asset/fonts/my_font.otf

I tried:

file:///android_res/font/my_font.otf

and many other ways of describing path to my font inside of res/font folder, but none of them work.

How to use custom font family for a WebView that loads html string if my font is stored in res/font folder ?

//Edit:

My current implementation that is not working is:

@BindingAdapter("loadData")
public static void loadData(WebView webView, String htmlData) {
    webView.loadDataWithBaseURL(null, htmlData, "text/html", "utf-8", null);
}

@BindingAdapter({"loadData", "fontFamily"})
public static void loadData(WebView webView, String htmlData, @FontRes int fontFamilyId) {
    TypedValue value = new TypedValue();
    ApplicationActivity.getSharedApplication().getResources().getValue(fontFamilyId, value, true);
    String fontPath = value.string.toString();
    File fontFile = new File(fontPath);

    String prefix = "<html>\n"
            +"\t<head>\n"
            +"\t\t<style type=\"text/css\">\n"
            +"\t\t\t@font-face {\n"
            +"\t\t\t\tfont-family: 'CustomFont';\n"
            +"\t\t\t\tsrc: url(\"file:///android_res/font/"+fontFile.getName()+"\")\n"
            +"\t\t\t}\n"
            +"\t\t\tbody {\n"
            +"\t\t\t\tfont-family: 'CustomFont';\n"
            +"\t\t\t}\n"
            +"\t\t</style>\n"
            +"\t</head>\n"
            +"\t<body>\n";
    String postfix = "\t</body>\n</html>";

    loadData(webView, prefix + htmlData + postfix);
}

Answer

hibob picture hibob · Nov 1, 2017

Just tried and this works similarly to loading fonts from assets, you just need to change the base url to point to resources instead.

Example HTML

<html>
<head>
    <style>
        @font-face {
            font-family: 'CustomFont';
            src: url('font/CustomFont.ttf');
        }
        #font {
            font-family: 'CustomFont';
        }
    </style>
</head>
<body>
    <p>No Font</p>
    <br />
    <p id="font">Font</p>
</body>

load this HTML into the webview using Webview#loadDataWithBaseURL(String, String, String, String, String), using file://android_res/ as the base url (first param)

Example:

webview.loadDataWithBaseURL("file:///android_res/", html, "text/html", "utf-8", null)

Edit:

If you're using proguard on your release builds you'll need to add extra rules to prevent the R class being renamed during the ProGuard process otherwise the WebView won't be able to find the font resource. Details can be found at this post