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

时间:2010-10-10 14:18:28

标签: 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);

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

谢谢!

15 个答案:

答案 0 :(得分:98)

this project中有一个有效的例子。归结为:

  1. assets/fonts文件夹中,放置所需的OTF或TTF字体(此处为MyFont.otf)
  2. assets文件夹(此处assets/demo/my_page.html内)中创建一个用于WebView内容的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");
    
  4. 请注意,不允许通过loadData()注入HTML。 As per the documentation

      

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

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

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

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

答案 1 :(得分:90)

我正在使用此代码

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

答案 2 :(得分:48)

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

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

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

...

答案 3 :(得分:25)

可以在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");

答案 4 :(得分:9)

我用上面的答案做了这个补充:

In [1]: X = IndexedBase("X")

In [2]: Y = IndexedBase("Y")

In [4]: beta = IndexedBase("beta")

In [5]: expr = Sum(Y[i]*exp(Sum(X[i, j]*beta[j], (j, 1, 5))), (i, 1, 20))

In [7]: pprint(expr)
  20                                 
_____                                
\    `                               
 \        5                          
  \      __                          
   \     \ `                         
    )     )   beta[j]*X[i, j]        
   /     /_,                         
  /     j = 1                        
 /     e                     *Y[i]
/____,                               
i = 1        

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

src: url("file:///android_asset/fonts/YourFont...


感谢大家:)

答案 5 :(得分:4)

如果您的资源文件夹中包含您的内容,上述答案中的许多工作都很有魅力。

但是,如果您希望我将所有资产从服务器下载并保存到内部存储,则可以使用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", "");

上面的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;
}

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

答案 6 :(得分:3)

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

答案 7 :(得分:1)

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

答案 8 :(得分:1)

问题是它需要放在一个文件夹中,试着把&#34; ./ myfont.ttf&#34;相反,如果不将字体放在资产中的文件夹中,如&#34; fonts / myfont.ttf&#34;这肯定会奏效。

答案 9 :(得分:0)

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

您还可以使用在线字体(例如Google的字体),这将有助于减小apk大小。

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

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

viewModel = ViewModelProviders.of(getActivity()).get(MyViewModel.class);

然后像这样加载网页视图

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中使用1种字体,在整个应用程序中使用不同的字体是没有意义的。因此,您可以在应用中使用Downloadable Fonts,该应用还使用外部资源在应用中加载字体。

答案 10 :(得分: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);
    }

答案 11 :(得分:0)

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

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

答案 12 :(得分: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");

答案 13 :(得分:0)

响应与 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)
    }
}

使用 loadDataWithBaseURL 加载 HTML 内容。

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

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()

答案 14 :(得分:-3)

这是如何在webview中加载htmlData的:

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

其中getHtmlData(activity,**htmlData**)返回一串html代码。