Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use custom font from res/font with WebView in Android

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);
}
like image 836
1daemon1 Avatar asked Sep 21 '17 13:09

1daemon1


3 Answers

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

like image 195
hibob Avatar answered Oct 16 '22 20:10

hibob


I managed to load my local font from res/font directory. In my example i want to load italic opensans.

My setup are as follow:

  1. css file inside assets directory
  2. use this for setting the font-face
    @font-face {
      font-family: 'opensans';
      src: url("file:///android_res/font/opensans_italic.ttf")
    }

    body {
      font-family: 'opensans';
      font-weight: 400;
    }
  1. Load the WebView using loadDataWithBaseUrl, for example:

    webView.loadDataWithBaseURL(null, yourHtmlContent, "text/html", "utf-8", null)

    But i have this at the the top of my html content: "<link rel='stylesheet' type='text/css' href='file:///android_asset/mycss.css' />”

    I hope it works too for your case.

Edit:

Add this in your proguard config to make it work in release mode.

-keep class com.your.package.name.R$font { *; }

like image 36
Reza Avatar answered Oct 16 '22 20:10

Reza


You can use the custom res font like this -

<head>
<style type="text/css">
    @font-face {
        font-family: MyFont;
        src: url("file:///res/font/myfont.ttf")
    }
    body {
        font-family: MyFont;
    }
</style>

like image 2
Harsh Avatar answered Oct 16 '22 21:10

Harsh