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


97

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

我尝试通过将自定义字体放入素材资源来获取自定义字体的实例。但是仍然无法将webview的默认字体设置为我的字体。

这是我尝试的:

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

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

谢谢!


最终我意识到这是无法完成的。
Dhanika 2010年


嗨,您是否找到了此字体外观的任何解决方案,我正在尝试印地语字体stackoverflow.com/q/5868198/501859。如果您有解决方案,请帮助我
Kishore

@Dhanika如何解决同一问题。
NagarjunaReddy

请参考此链接集自定义字体在网页视图文本.. stackoverflow.com/a/25692052/3921740[1] :[1] stackoverflow.com/a/25692052/3921740
user3921740

Answers:


111

这个项目中有一个可行的例子。归结为:

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

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

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

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

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

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


10
LoadData()不工作,但webView.loadDataWithBaseURL(“文件:/// android_asset /”,......工作正常然后还字体文件引用为“/fonts/MyFont.otf”应该工作
JaakL

就我而言,数据以ck编辑器(后端api)的标签形式返回。<div style = \“ text-align:center; \”> <span style =“ \” background-color:transparent; \“> <字体颜色= \“#f20505 \” size = \“ 5 \” face = \“ Comic Sans MS \”>请与我们分享您的反馈<\ / font> <\ / span>我将其设置为webview.loadData ()但不带字体,任何解决方案?
B.shruti

不是Android提供的Comic Sans MS字体。仅当您在CSS中定义了字体并在应用程序资源中提供了字体文件时,此方法才有效。
Paul Lammertsma,

2
我的字体位于res/font文件夹中。那路是什么?我尝试过,file:///android_res/font/但似乎没有用。
旋转

105

我正在使用此代码

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
我的天啊!这正是使我们走到发生问题的线索的地方:事实证明,如果在“ src:url('...”后面添加“ format('ttf')”,则Android 4.2不会渲染字体。 ')“子句。忽略它,字体呈现精美。经过Google自己的网络字体测试。
Pascal Lindelauf 2014年

2
竖起大拇指,这是个摇摆不定的解决方案
Saad Bilal 2015年

loadDataWithBaseURL在android 4.1和4.2版本上
不起作用

在Android 5.1中对我不起作用。我使用了(Dan Syrstad)的答案。不同的是报价font-family: 'myface';
Mneckoee

52

更简单的是,您可以使用素材资源网址格式来引用字体。无需编程!

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

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

...


1
如果我将.ttf.html文件放在同一目录中,然后将其加载到Android浏览器中,则可以正常工作。但是,在我的应用程序的WebView中,尽管CSS出现了,但尽管将文本添加.ttf到了项目的assets/fonts文件夹中,但文本仍以Android的默认字体显示。我正在2.3.5上进行测试,但针对2.1进行了构建。可能是问题所在,还是我想念什么?
Paul Lammertsma 2011年

1
我找到了解决方法:如果您创建HTML文件并将其放置在资产中,则可以通过view.loadUrl()Works 加载它,而view.loadData()不会。我不知道后者为什么不这样做。
Paul Lammertsma 2011年

4
有点晚了,但是可以和view.loadDataWithBaseUrl(null,content,mime,enconding,null)一起使用
我们的

28

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

嗨!我尝试了这种方法,但是WebView仍然无法加载我的字体。你有什么特别的吗?谢谢!
Zarah 2011年

如何针对html stackoverflow.com/q/5868198/501859进行操作。如果您有解决方案,请帮助我
Kishore

对我有用。感谢Binary。
拉维·香克

我在资产文件夹中拥有字体,并在正文中更改了具有该字体和字体家族名称的完整路径的CSS,并且在修改后我再次加载了内容,但无法立即看到字体更改的效果
Ravi 2014年

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


感谢大家:)


完美答案!
SANAT

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

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

2
请改善您的问题,并附上您所做的解释。
lifeisfoo

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


1

您可以使用CSS来实现。我使用某个应用程序完成了此操作,但由于Android浏览器2.1存在一个已知的错误,因此无法在Android 2.1中运行。


1

问题是它需要放在文件夹中,如果没有将字体放在肯定可以工作的资产(例如“ fonts / myfont.ttf”)中,请尝试将“ ./myfont.ttf”放入文件夹中。


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

0

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

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

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

-3

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

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.