106

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

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

这是我尝试过的:

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

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

谢谢!

4

15 回答 15

116

在这个项目中有一个工作示例。它归结为:

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

    <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>
    
  3. 从代码中将 HTML 加载到 WebView 中:

    webview.loadUrl("file:///android_asset/demo/my_page.html");
    

请注意,loadData()不允许通过注入 HTML。根据文档

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

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

webView.loadDataWithBaseURL("file:///android_asset/", htmlData);

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

于 2011-09-12T23:23:15.277 回答
110

我正在使用这段代码

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);
于 2014-02-20T13:04:43.603 回答
53

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

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

body { 
   font-family: 'myface', serif;

...

于 2011-04-20T21:57:09.190 回答
29

它可以在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;
    }

3.您只需调用一次上述函数(您必须为此找到一些逻辑)。

copyFile(getContext(), "myfont.ttf");

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

5.您可以如下调用上述函数

webview.loadDataWithBaseURL(null, getHtmlData(activity,htmlData) , "text/html", "utf-8", "about:blank");
于 2011-03-24T10:26:27.960 回答
13

我通过上面的答案完成了这个添加:

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

然后使用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>" : "");
}


谢谢大家:)

于 2016-06-08T15:22:56.420 回答
6

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

但是,如果您像我一样想将所有资产从服务器下载并保存到内部存储,您可以改为使用loadDataWithBaseURL和使用对内部存储的引用作为 baseUrl。然后那里的所有文件都将与加载的 html 相关,并被正确找到和使用。

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

  • IndigoAntiqua2Text-Regular.ttf
  • 样式.css
  • 图像.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", "");

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

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

.running{
    color: #565656;
     font-family: "MyCustomRunning";
     font-size: 48px;
}

我只在针对 minSdkVersion 19 (4.4) 时尝试过这个,所以我不知道它是否适用于其他版本

于 2015-06-24T23:00:31.380 回答
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);
于 2017-09-03T12:58:42.967 回答
5

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

@font-face {
     font-family: yourfont;
     src: url("file:///android_res/font/yourfont.ttf")
}
        
body {
     font-family: yourfont;
}
于 2020-07-17T01:48:53.510 回答
5

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

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

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

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

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

使用 加载 HTML 内容loadDataWithBaseURL

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

返回您的getStyledHtmlContentHTML 内容。

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()
于 2021-06-30T23:36:08.017 回答
2

您无需使用本地 ttf 文件为 android 设置 webview 字体,它会增加整个应用程序的大小。

您还可以使用在线字体,如 google 的字体...这将有助于减少您的 apk 大小。

例如:访问以下网址 https://gist.github.com/karimnaaji/b6c9c9e819204113e9cabf290d580551#file-googlefonts-txt

您将找到使用此字体的必要信息。然后创建一个如下所示的字符串

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;}";

然后像这样加载webview

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

完毕。您将能够以这种方式从外部源加载字体。

现在关于应用程序字体,为 webview 使用 1 种字体并为整个应用程序使用不同的字体是没有意义的。因此,您可以在您的应用程序中使用可下载字体,它还使用外部资源在应用程序中加载字体。

于 2019-07-27T04:58:08.740 回答
1

您可以使用 CSS 来实现。我是用一个应用程序完成的,但它在 Android 2.1 中不起作用,因为 Android 浏览器 2.1 存在一个已知错误。

于 2011-02-13T15:30:17.457 回答
1

问题是它需要放在一个文件夹中,请尝试将“./myfont.ttf”放在一个文件夹中,如果不将字体放在“fonts/myfont.ttf”之类的资产文件夹中,那肯定会起作用。

于 2013-07-12T19:29:09.963 回答
0

使用https://github.com/delight-im/Android-AdvancedWebView库。

在 html 数据中:

<!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>

在 xml 中:

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

在java中:

advancedWebView = findViewById(R.id.advanced_web_view);
advancedWebView.loadHtml(htmlData, "text/html; charset=utf-8", "utf-8");
于 2020-08-01T07:13:03.877 回答
0

测试它,像魅力一样为我工作:

   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);
    }
于 2019-11-06T16:03:13.193 回答
-3

这是在 webview 中加载 htmlData 的方式:

webview.loadDataWithBaseURL(null, getHtmlData(activity,**htmlData**) , "text/html", "utf-8", "about:blank");

wheregetHtmlData(activity,**htmlData**)返回一串 html 代码。

于 2013-07-10T02:52:13.230 回答