如何在Android中更改Webview的字体?

Dha*_*ika 93 android webview font-face custom-font

我想将webview的默认字体更改为自定义字体.我正在使用webview开发Android的双语浏览器应用程序.

我尝试通过将自定义字体放在资源中来获取自定义字体的实例.但仍然无法将webview的默认字体设置为我的字体.

这是我试过的:

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

任何人都可以更正此或建议任何其他方法将webview的默认字体更改为自定义字体?

谢谢!

Pau*_*sma 106

这个项目有一个很好的例子.归结为:

  1. 在您的assets/fonts文件夹中,放置所需的OTF或TTF字体(此处为MyFont.otf)
  2. assets文件夹内(此处为内部assets/demo/my_page.html)创建一个HTML文件,用于WebView的内容:

    <html>
    <head>
    <style type="text/css">
    @font-face {
        font-family: MyFont;
        src: url("file:///android_asset/fonts/MyFont.otf")
    }
    body {
        font-family: MyFont;
        font-size: medium;
        text-align: justify;
    }
    </style>
    </head>
    <body>
    Your text can go here! Your text can go here! Your text can go here!
    </body>
    </html>
    
    Run Code Online (Sandbox Code Playgroud)
  3. 从代码中将HTML加载到WebView中:

    webview.loadUrl("file:///android_asset/demo/my_page.html");
    
    Run Code Online (Sandbox Code Playgroud)

请注意,loadData()不允许注入HTML .根据文件:

请注意,JavaScript的相同原始策略意味着在使用此方法加载的页面中运行的脚本将无法访问使用"数据"以外的任何方案加载的内容,包括"http(s)".要避免此限制,请将loadDataWithBaseURL()与适当的基本URL一起使用.

正如@JaakL在下面的评论中建议的,要从字符串加载HTML,您应该提供指向您的资产的基本URL:

webView.loadDataWithBaseURL("file:///android_asset/", htmlData);
Run Code Online (Sandbox Code Playgroud)

在引用字体时htmlData,您可以简单地使用/fonts/MyFont.otf(省略基本URL).

  • LoadData()不起作用,但webView.loadDataWithBaseURL("file:/// android_asset /",...工作正常.然后字体文件引用为"/fonts/MyFont.otf"应该有效. (9认同)
  • 我的字体位于“res/font”文件夹中。那时的路会怎样呢?我尝试了“file:///android_res/font/”,但它似乎不起作用。 (3认同)

Omi*_*idi 98

我正在使用此代码:

wv = (WebView) findViewById(R.id.webView1);
String pish = "<html><head><style type=\"text/css\">@font-face {font-family: MyFont;src: url(\"file:///android_asset/font/BMitra.ttf\")}body {font-family: MyFont;font-size: medium;text-align: justify;}</style></head><body>";
String pas = "</body></html>";
String myHtmlString = pish + YourTxext + pas;
wv.loadDataWithBaseURL(null,myHtmlString, "text/html", "UTF-8", null);
Run Code Online (Sandbox Code Playgroud)

  • 这是正确的解决方案.谢谢!! (6认同)
  • 我的天啊!这正是让我们发现出了什么问题的原因:事实证明,如果在“src: url('... ')" 条款。将其排除在外,字体呈现精美。使用 Google 自己的网络字体进行测试。 (2认同)
  • 这是摇摆解决方案,竖起大拇指 (2认同)

Dan*_*tad 50

更简单的是,您可以使用资产URL格式来引用字体.无需编程!

@font-face {
   font-family: 'myface';
   src: url('file:///android_asset/fonts/myfont.ttf'); 
} 

body { 
   font-family: 'myface', serif;
Run Code Online (Sandbox Code Playgroud)

...

  • 一个lil'迟到了,但它适用于view.loadDataWithBaseUrl(null,content,mime,enconding,null) (4认同)

bin*_*ary 27

它可以在Android中完成.我花了三天时间来解决这个问题.但现在看起来很容易.请按照以下步骤为Webview设置自定义字体

1.将您的字体添加到资源文件夹2.
将字体复制到应用程序的文件目录

private boolean copyFile(Context context,String fileName) {
        boolean status = false;
        try { 
            FileOutputStream out = context.openFileOutput(fileName, Context.MODE_PRIVATE);
            InputStream in = context.getAssets().open(fileName);
            // Transfer bytes from the input file to the output file
            byte[] buf = new byte[1024];
            int len;
            while ((len = in.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
            // Close the streams
            out.close();
            in.close();
            status = true;
        } catch (Exception e) {
            System.out.println("Exception in copyFile:: "+e.getMessage());
            status = false;
        }
        System.out.println("copyFile Status:: "+status);
        return status;
    }
Run Code Online (Sandbox Code Playgroud)

你只需要调用一次上面的函数(你必须找到一些逻辑).

copyFile(getContext(), "myfont.ttf");
Run Code Online (Sandbox Code Playgroud)

4.使用以下代码为webview设置值.这里我使用CSS来设置字体.

private String getHtmlData(Context context, String data){
    String head = "<head><style>@font-face {font-family: 'verdana';src: url('file://"+ context.getFilesDir().getAbsolutePath()+ "/verdana.ttf');}body {font-family: 'verdana';}</style></head>";
    String htmlData= "<html>"+head+"<body>"+data+"</body></html>" ;
    return htmlData;
 }
Run Code Online (Sandbox Code Playgroud)

你可以按以下方式调用上述功能

webview.loadDataWithBaseURL(null, getHtmlData(activity,htmlData) , "text/html", "utf-8", "about:blank");
Run Code Online (Sandbox Code Playgroud)


Vla*_*lad 12

我用上面的答案做了这个添加:

webView.loadDataWithBaseURL("file:///android_asset/",
                            WebClient.getStyledFont(someText),
                            "text/html; charset=UTF-8", null, "about:blank");
Run Code Online (Sandbox Code Playgroud)

然后使用 src: url("file:///android_asset/fonts/YourFont...

public static String getStyledFont(String html) {
    boolean addBodyStart = !html.toLowerCase().contains("<body>");
    boolean addBodyEnd = !html.toLowerCase().contains("</body");
    return "<style type=\"text/css\">@font-face {font-family: CustomFont;" +
            "src: url(\"file:///android_asset/fonts/Brandon_reg.otf\")}" +
            "body {font-family: CustomFont;font-size: medium;text-align: justify;}</style>" +
            (addBodyStart ? "<body>" : "") + html + (addBodyEnd ? "</body>" : "");
}
Run Code Online (Sandbox Code Playgroud)


谢谢大家:)


Ibr*_*Ali 7

如果您像我一样将字体放在下面res/font,那么您可以将目录更改为以下内容:-

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


lej*_*onl 6

如果您的资产文件夹中有内容,则上述许多答案的工作都非常有魅力。

但是,如果像我这样想要将所有资产从服务器下载并保存到内部存储中,则可以使用loadDataWithBaseURL内部存储的引用并将其用作baseUrl。然后,所有文件都将相对于已加载的html,并且可以正确找到和使用。

在我的内部存储器中,我保存了以下文件:

  • IndigoAntiqua2Text-Regular.ttf
  • style.css
  • image.png

然后,我使用以下代码:

WebView web = (WebView)findViewById(R.id.webby);
//For avoiding a weird error message
web.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

String webContent = "<!DOCTYPE html><html><head><meta charset=\"UTF-8\"><link rel=\"stylesheet\" href=\"style.css\"></head>"
                            + "<body><img src='image.png' width=\"100px\"><div class=\"running\">I am a text rendered with INDIGO</div></body></html>";

String internalFilePath = "file://" + getFilesDir().getAbsolutePath() + "/";
web.loadDataWithBaseURL(internalFilePath, webContent, "text/html", "UTF-8", "");
Run Code Online (Sandbox Code Playgroud)

上面的html(style.css)中使用的CSS文件:

@font-face {
  font-family: 'MyCustomRunning';
  src: url('IndigoAntiqua2Text-Regular.ttf')  format('truetype');
}

.running{
    color: #565656;
     font-family: "MyCustomRunning";
     font-size: 48px;
}
Run Code Online (Sandbox Code Playgroud)

我只在针对minSdkVersion 19(4.4)时尝试过此操作,所以我不知道它是否可以在其他版本上使用


小智 6

 webview= (WebView) findViewById(R.id.webview);
 String myCustomStyleString="<style type=\"text/css\">@font-face {font-family: MyFont;src: url(\"file:///android_asset/fonts/iranian_sans.ttf\")}body,* {font-family: MyFont; font-size: 13px;text-align: justify;}img{max-width:100%;height:auto; border-radius: 8px;}</style>";
 webview.loadDataWithBaseURL("", myCustomStyleString+"<div style=\"direction:rtl\">"+intentpost.getStringExtra("content")+"</div>", "text/html", "utf-8", null);
Run Code Online (Sandbox Code Playgroud)

  • 请改进您的问题,添加对您在做什么的解释。 (2认同)

ngl*_*ber 5

响应兼容Android 11(API 30)或更高版本。

我看到了很多答案,但没有一个适用于 Android 11+。对我来说,解决方案是:WebAssetLoader

val assetLoader = WebViewAssetLoader.Builder()
    .addPathHandler(
        "/res/", 
        WebViewAssetLoader.ResourcesPathHandler(context))
    .build()
Run Code Online (Sandbox Code Playgroud)

就我而言,字体位于res/font文件夹中。

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

使用 加载 HTML 内容loadDataWithBaseURL

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

返回getStyledHtmlContent您的 HTML 内容。

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()
Run Code Online (Sandbox Code Playgroud)


Jay*_*ayu 1

您可以使用 CSS 来做到这一点。我用一个应用程序做到了这一点,但它在 Android 2.1 中不起作用,因为 Android 浏览器 2.1 存在一个已知错误。