16

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);
}
1daemon1
  • 1,001
  • 3
  • 11
  • 29
  • Possible duplicate of [How to change font face of Webview in Android?](https://stackoverflow.com/questions/3900658/how-to-change-font-face-of-webview-in-android) – Kunu Sep 21 '17 at 13:09
  • 6
    It's not duplicate. I mentioned that topic - it describes loading fonts from assets folder, I am talking about loading font from res folder and new android font support. – 1daemon1 Sep 21 '17 at 13:11
  • Why don't change font by css? – Steven Sep 21 '17 at 17:06
  • @Steven isn't that what I am trying to do ? I am using css to change the font, I just don't know how to set the path to the font in res/font folder. – 1daemon1 Sep 22 '17 at 07:32
  • I mean why do It like that. When you just can create a css file and change the style in their? – Steven Sep 22 '17 at 15:36
  • 3
    Good Question, especially regarding the new possibility of Android Studio 3 to support fonts to be added directly via res/font folder. – Elementary Nov 09 '17 at 15:32

3 Answers3

17

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

hibob
  • 746
  • 7
  • 17
  • Hi, does this really work? I try it but webview logs exception "Unable to open resource URL: file:///android_res/font/ubuntu_regular.ttf" "java.lang.ClassNotFoundException: Didn't find class "com.xxx.yyy.zzz.R$font" on path:" – Petr Daňa Mar 19 '18 at 14:09
  • @PetrDaňa just came across this issue myself, seems to only be an issue with proguarded builds caused by the fact that proguard is renaming the `R` resources file and the webview therefore cannot find it. Solution is to use the proguard rules listed on [this post](https://stackoverflow.com/questions/6280188/prevent-proguard-to-remove-specific-drawables?answertab=votes#tab-top) – hibob Jul 04 '18 at 15:45
  • does not work for me: `Failed to load resource: net::ERR_FILE_NOT_FOUND` in the WebViews Console – Till Krempel Sep 24 '18 at 09:07
  • For those who have an exception like `java.lang.ClassNotFoundException: Didn't find class "your.package.name.R$font"`. The cause may be that you have different applicationId's for debug/release or flavored builds. You may find the explanation here: https://stackoverflow.com/questions/23469712/file-android-res-drawable-not-working-when-using-flavor-with-other-package-na – Kirill Starostin Jul 23 '19 at 16:45
  • Even added package in proguard file but still, it's not working. – Anshul Tyagi Oct 06 '21 at 11:55
11

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 { *; }

Reza
  • 1,164
  • 11
  • 9
  • worked for me, don't forget to create font folder in res by right clicking -> new -> Android Resource Directory. and also the name can only be in minuscule with _ and not - – XCarb Jul 29 '20 at 14:56
3

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>

Harsh
  • 460
  • 5
  • 9