How to change font face of Webview in Android?

Viewed 110833

I want change the default font of webview to a custom font. I'm using webview in developing an bilingual browser app for Android.

I tried getting an instance of custom typeface by placing my custom font in assets. But still couldn't set webview's default font to my font.

This is what I tried:

Typeface font = Typeface.createFromAsset(getAssets(), "myfont.ttf"); 
private WebView webview;
WebSettings webSettings = webView.getSettings();
webSettings.setFixedFontFamily(font);

Can anyone correct this or suggest any other method to change webview's default font to a custom font?

Thanks!

15 Answers

If you are putting fonts under res/font like me, then you can change the dir to the following:-

@font-face {
     font-family: yourfont;
     src: url("file:///android_res/font/yourfont.ttf")
}
        
body {
     font-family: yourfont;
}

Response compatible with Android 11 (API 30) or above.

I saw a lot of answers, but none of them was working on Android 11+. For me, the solution was: WebAssetLoader.

val assetLoader = WebViewAssetLoader.Builder()
    .addPathHandler(
        "/res/", 
        WebViewAssetLoader.ResourcesPathHandler(context))
    .build()

In my case, the font is in res/font folder.

webView.webViewClient = object : WebViewClient() {
    ...
    override fun shouldInterceptRequest(
        view: WebView,
        request: WebResourceRequest
    ): WebResourceResponse? {
        return assetLoader.shouldInterceptRequest(request.url)
    }
}

Load the HTML content using loadDataWithBaseURL.

webView.loadDataWithBaseURL(
    "https://appassets.androidplatform.net",
    getStyledHtmlContent(),
    "text/html",
    "UTF-8",
    null
)

The getStyledHtmlContent returns your HTML content.

private fun getStyledHtmlContent() =
    """
    <html>
    <head>
        <style>
            @font-face {
                font-family: 'AnyNameYouWant';
                src: url('https://appassets.androidplatform.net/res/font/yourfont.otf');
            }
            body {
                font-family: AnyNameYouWant;
                line-height: 1.5;
                text-align: justify;
            }
        </style>
    </head>
    <body>Content of your page</body>
    </html>
    """.trimIndent()

You need not use local ttf file to set webview font for android, It will increase the whole app size.

you can also use online fonts like google's font... It will help to reduce your apk size.

For example: visit the below URL https://gist.github.com/karimnaaji/b6c9c9e819204113e9cabf290d580551#file-googlefonts-txt

You will found necessary info to use this font. then create a String like below

String font = "@font-face {font-family: MyFont;src: url(\"here you will put the url of the font which you get previously\")}body {font-family: MyFont;font-size: medium;text-align: justify;}";

then load the webview like this

webview.loadDataWithBaseURL("about:blank", "<style>" +font+</style>" + "your html contnet here", "text/html", null, null);

done. You will able to load the font from the external source in this way.

Now whats about the app font, it doesn't make sense to use 1 font for the webview and different font for the whole app. So you can use Downloadable Fonts in your app which also uses external sources for loading fonts in the app.

You can do it by using CSS. I did it with an app but it won't work in Android 2.1 as there is an known bug with Android browser 2.1.

test it, work for me like a charm :

   private void setResult() {

        String mimeType = "text/html;charset=UTF-8";
        String encoding = "utf-8";
        String htmlText = htmlPrivacy;

        String text = "<html><head>"
                + "<style type=\"text/css\">@font-face {font-family: MyFont;src: url(\"file:///android_asset/fonts/iy_reg.ttf\")}body{font-family: MyFont;color: #666666}"
                + "</style></head>"
                + "<body>"
                + htmlText
                + "</body></html>";

        webView.loadDataWithBaseURL(null, text, mimeType, encoding, null);
    }

Use https://github.com/delight-im/Android-AdvancedWebView library.

in html data :

<!doctype html>
<html>

<head>
<style type="text/css">
@font-face {
    font-family: MyFont;
    src: url("file:///android_asset/fonts/font1.ttf")
}
body {
    font-family: MyFont;
    font-size: medium;
    text-align: justify;
}
</style>
<meta http-equiv="Content-Type" content="text/html;  charset=utf-8">
<title>Title</title>
</head>

<body>

    ------ YOUR_CONTENT ------

</body>

</html>

in xml :

<im.delight.android.webview.AdvancedWebView
    android:id="@+id/advanced_web_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

in java :

advancedWebView = findViewById(R.id.advanced_web_view);
advancedWebView.loadHtml(htmlData, "text/html; charset=utf-8", "utf-8");
Related