如何在WebView中使用自定义字体

62

现在我想显示一些 Unicode 字符,我使用了标签:<font face="Arial">something here</font>。但是似乎 WebView 找不到 Arial 字体,因为我只能看到 UFO 字符。我需要将 arial.ttf 拷贝到某个地方吗?或者我该如何在 WebView 中使用这个 TrueType 字体?谢谢。

10个回答

82

loadData 对我也不起作用,所以我在 src 路径中使用了 file:///android_asset

我使用 loadDataWithBaseURL 时它起作用了!

对于这个例子,我更改了 CSS 为:

@font-face {
    font-family: 'feast';
    src: url('fonts/feasfbrg.ttf');
}

body {font-family: 'feast';}

然后使用资产路径作为基本URL:

loadDataWithBaseURL("file:///android_asset/",myhtml,"text/html","utf-8",null);

我在将CSS放入“strings.xml”中遇到了问题。因此,我创建了一个包含上述CSS值的字符串常量,这样就能显示自定义字体效果。谢谢! - Mahendra Liya
1
你刚刚让我开心了!! :) - Gaurav Arora
1
请确保字体路径正确,并且不以“/”开头(例如'/fonts/feasfbrg.ttf')。 - Marqs
你让我今天心情大好!!谢谢!我错过了基础URL。 - JHawkZZ

34

据 @raychung 的建议,显然可以为 WebView 使用自定义字体。但这在 2.1 版本中无法使用(问题报告在此处)。这应该适用于 1.5、1.6 和 2.2 版本。

您可以将自定义 TTF 文件放入/assets 文件夹中,然后在 CSS 文件中添加如下代码:

@font-face { 
    font-family: "myIPA"; 
    src: url('IPA.TTF'); 
}
.phon, .unicode
{
    display: inline;    
    font-family: 'myIPA', Verdana, sans-serif;  
    font-size: 14pt;
    font-weight: 500;
    font-style:normal;
    color: black;
}

现在你可以在HTML文件中引用此字体样式。


2
如果我将.ttf.html文件放在同一个目录中,并在Android浏览器中加载它,它可以正常工作。但是在我的应用程序的WebView中,虽然CSS显示出来了,但文本仍然出现在Android的默认字体中,尽管已将.ttf添加到项目的assets文件夹中。我正在2.3.5上进行测试,但针对2.1构建。这可能是问题所在,还是我漏掉了什么? - Paul Lammertsma
1
我找到了一个解决方案:如果您创建一个 HTML 文件并将其放置在资产中,则通过 view.loadUrl() 加载它可以工作,而 view.loadData() 则不行。我不知道为什么后者不能。 - Paul Lammertsma
嘿@Paul!这很奇怪。我已经有一段时间没有尝试解决这个错误了,但是当我需要时,我会尝试你的解决方法。以前我所做的就是将HTML文件中的特殊字符更改为图像。 - Zarah
1
如果有用的话,可以查看我的更详细的答案和示例。 - Paul Lammertsma
顺便提一下,如果您想为多种不同的语言使用多种不同的字体,这也是可行的。我将我的结构设置如下:font-family: Verdana, sans-serif, language1, language2, language3 ---> 尽管您必须限制前两个的UTF范围才能实现这一点。 - Kaiesh
它对我没有起作用。我将URL更改为src:url('file:///android_asset/TAHOMA.TTF'),然后它就起作用了。 - Bobs

3

您可以通过将字体文件从资产文件夹复制到应用程序的文件夹中,在应用程序首次启动时使其在所有版本上正常工作,然后将其引用为:

"@font-face {
 font-family: cool_font;
 src: url('file://"+ getFilesDir().getAbsolutePath() 
  + "/cool_font.ttf');
}"

将文件复制到我的文件夹中还是无法正常工作。WebView仍然没有使用我的字体。你做了什么特别的吗? - Zarah
实际上,在第一次启动时,我会检查文件是否已经复制到文件夹中,如果没有,我会将其复制,然后按照之前所述进行引用。File f = new File(getFilesDir(), "coolFont.ttf"); if (f.length() == 0) { InputStream myInput = this.getAssets().open("fonts/coolFont.ttf"); String outFileName = "coolFont.ttf"; OutputStream myOutput = new FileOutputStream(getFilesDir() + "/" + outFileName); byte[] buffer = new byte[1024]; int length; while ((length = myInput.read(buffer)) > 0) { myOutput.write(buffer, 0, length); } myOutput.flush(); myOutput.close(); myInput.close(); } - Felipe Martinez Carreño
我一直没有成功让它工作。我的字体出现在应用程序的/data/data/[package]/files目录中,虽然WebView根据CSS进行了样式化,但文本却没有以所需的字体显示。我正在构建Android 2.1并在2.3.5上进行测试。有什么线索吗? - Paul Lammertsma

3
我使用以下代码进行从右向左的排版和波斯字体,希望有人使用过这段代码或者能够建议更好的方法。谢谢。
            String myCustomStyleString="<style type=\"text/css\">@font-face {font-family: MyFont;src: url(\"file:///android_asset/fonts/BYEKAN.ttf\")}body,* {font-family: MyFont; font-size: medium;text-align: justify;}</style>";
                    webView.loadDataWithBaseURL("", myCustomStyleString+"<div style=\"direction:rtl\">"+myHtm+"</div>", "text/html", "utf-8", null);

3
@font-face {
 font-family: 'MyCustomFont';
 src: url('/assets/fonts/MaycustomFont.ttf') 
}

这对我有效。

->src
->assets
   ->fonts
      ->MaycustomFont.ttf
->..
->res

2

它对我无效,在使用本地文件的引用之前,我不得不链接字体到我的网络服务器:

   @font-face {
   font-family: 'feast';
   src: url('http://yoursite.com/tutorial/css/feasfbrg.ttf');
}

body {font-family: 'feast';}

2

我在测试的所有设备上都能很好地运行。

将您的字体文件放置在 /src/main/assets/fonts 中,然后使用以下方法:

public class HTMLUtils {

    public static String getLocalFontInHTML(String html, String fontFamily, String fontFileName) {

      return "<!DOCTYPE html>\n" +
            "<html>\n" +
            "<head>\n" +
            "<style>" +
            "@font-face {" +
            "font-family: " + fontFamily + ";" +
            "src: url('" + fontFileName + "');" +
            "}" +
            "* {font-family: '" + fontFamily + "' !important;}" +
            "* {font-size: 1rem !important;}" +
            "</style>" +
            "</head>\n" +
            "<body>\n" +
            html +
            "\n" +
            "</body>\n" +
            "</html>";
     }
}

as follows

webView.loadDataWithBaseURL("file:///android_asset/", HTMLUtils.getLocalFontInHTML(item.text, Config.FONT_FAMILY, Config.REGULAR_FONT),"text/html", "UTF-8", null);

在哪里

public static final String FONT_FAMILY = "Montserrat";

public static final String REGULAR_FONT = "fonts/Montserrat-Regular.otf";

希望对某些人有所帮助!

如果您想保留HTML代码中的字体大小,请删除

 "* {font-size: 1rem !important;}"

请注意,1rem相当于约14sp。

1

基本思路是网页应该可以访问字体文件。这就是为什么建议的原始解决方案在HTML文件和字体文件都在资产文件夹中,并且从那里加载HTML文件时有效。

这不是Android的功能,而是CSS,因此应该适用于任何Android SDK。

如果字体文件确实存在并且样式中给出了正确的路径,则从文件夹中加载字体也应该有效。但是这种方法比较麻烦,需要编写代码来复制文件,然后编写代码来确定文件的位置。

我很高兴只需将HTML内容和字体文件放在资产中,并从那里加载。

webView.loadUrl("file:///android_asset/content.html");

1
如Felipe Martinez Carreño所说,您可以从资产中复制并且它会起作用。
您可以参考this以获取更多详细信息。

0
使用CSS
    @font-face {
     font-family: cool_font;
     src: url('cool_font.ttf');
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接