Como alterar a face da fonte do Webview no Android?


97

Quero mudar a fonte padrão do webview para uma fonte personalizada. Estou usando o webview para desenvolver um aplicativo de navegador bilíngue para Android.

Tentei obter uma instância de fonte personalizada colocando minha fonte personalizada em recursos. Mas ainda não consegui definir a fonte padrão do webview para minha fonte.

Isso é o que eu tentei:

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

Alguém pode corrigir isso ou sugerir qualquer outro método para alterar a fonte padrão do webview para uma fonte personalizada?

Obrigado!


Finalmente percebi que isso não pode ser feito.
— Dhanika


oi você encontrou alguma solução para essa coisa de rosto de fonte, estou tentando para a fonte hindi stackoverflow.com/q/5868198/501859 . me ajude se você tiver a solução
— Kishore

@Dhanika como resolver este problema enfrentando o mesmo problema.
— NagarjunaReddy

Consulte este link para definir a fonte personalizada no texto da
— visualização da web

Respostas:


111

Há um exemplo prático disso neste projeto . Tudo se resume a:

  1. Em sua assets/fontspasta, coloque a fonte OTF ou TTF desejada (aqui MyFont.otf)
  2. Crie um arquivo HTML que você usará para o conteúdo do WebView, dentro da assetspasta (aqui dentro 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. Carregue o HTML no WebView a partir do código:

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

Observe que injetar o HTML por meio loadData()não é permitido. Conforme a documentação :

Observe que a mesma política de origem do JavaScript significa que o script em execução em uma página carregada usando este método não poderá acessar o conteúdo carregado usando qualquer esquema diferente de 'dados', incluindo 'http (s)'. Para evitar essa restrição, use loadDataWithBaseURL () com uma URL base apropriada.

Como @JaakL sugere no comentário abaixo, para carregar HTML de uma string, você deve fornecer o URL base apontando para seus ativos:

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

Ao fazer referência à fonte em htmlData, você pode simplesmente usar /fonts/MyFont.otf(omitindo o URL base).


10
LoadData () não funciona, mas webView.loadDataWithBaseURL ("file: /// android_asset /", ... funciona bem. Então, também a referência de arquivo de fonte como "/fonts/MyFont.otf" deve funcionar.
— JaakL

No meu caso, os dados estão retornando na forma de tags do ck editor (backend api) <div style = \ "text-align: center; \"> <span style = \ "background-color: transparent; \"> < font color = \ "# f20505 \" size = \ "5 \" face = \ "Comic Sans MS \"> Compartilhe seus comentários conosco <\ / font> <\ / span> Estou definindo como webview.loadData () mas não está levando fontes, alguma solução ??
— B.shruti

Comic Sans MS não é uma fonte fornecida pelo Android. Ele só funcionará se você tiver definido a face da fonte em CSS e fornecido o arquivo de fonte nos ativos do seu aplicativo.
— Paul Lammertsma

2
minha fonte está localizada na res/fontpasta. Qual seria o caminho então? Eu tentei, file:///android_res/font/mas não parece funcionar.
— Wirling em

105

Estou usando este código :

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
AMD! ISSO é exatamente o que nos colocou na pista do que estava acontecendo de errado: como se viu, o Android 4.2 NÃO renderiza a fonte se você adicionar o "formato ('ttf')" atrás de "src: url ('... ') "cláusula. Deixe isso de fora e as fontes serão renderizadas lindamente. Testado com as próprias fontes da web do Google.
— Pascal Lindelauf

2
Esta é uma solução incrível, Polegar para cima
— Saad Bilal

loadDataWithBaseURL não funciona nas versões Android 4.1 e 4.2 :(
— Misha Akopov

não funcionou para mim no Android 5.1. Usei a resposta de (Dan Syrstad). a diferença é a cotaçãofont-family: 'myface';
— Mneckoee

52

Ainda mais simples, você pode usar o formato de URL do ativo para fazer referência à fonte. Nenhuma programação necessária!

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

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

...


1
Se eu colocar o arquivo .ttfe .htmlno mesmo diretório e carregá-lo no navegador Android, ele funciona. No entanto, no WebView do meu aplicativo, enquanto o CSS é mostrado, o texto aparece na fonte padrão do Android, apesar de adicionar o .ttfà assets/fontspasta do projeto . Estou testando no 2.3.5, mas construindo contra o 2.1. Pode ser esse o problema ou há algo que estou perdendo?
— Paul Lammertsma

1
Eu encontrei uma solução: se você criar um arquivo HTML e colocá-lo nos ativos, carrega-o via view.loadUrl()works, enquanto view.loadData()não. Não tenho ideia de por que o último não o faz.
— Paul Lammertsma

4
Um pouco tarde, mas funciona com view.loadDataWithBaseUrl (null, content, mime, enconding, null)
— Nosso, em

28

Isso pode ser feito no Android. Levei três dias para resolver esse problema. Mas agora parece muito fácil. Siga estas etapas para definir a fonte personalizada para o Webview

1. Adicione sua fonte à pasta de ativos
2.Copie a fonte para o diretório de arquivos do aplicativo

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.Você deve chamar a função acima apenas uma vez (você deve encontrar alguma lógica para isso).

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

4. Use o código abaixo para definir o valor para sua visualização na web. Aqui estou usando CSS para definir a fonte.

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. Você pode chamar a função acima conforme abaixo

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

Oi! Tentei essa abordagem, mas o WebView ainda não carrega minha fonte. Você fez alguma coisa especial? Obrigado!
— Zarah

como fazer isso para html stackoverflow.com/q/5868198/501859 . me ajude se você tiver a solução
— Kishore

Funciona para mim. Obrigado, binário.
— Ravi Shanker Yadav

Estou colocando a fonte na pasta de ativos e alterando o css com o caminho completo da fonte e o nome da família da fonte no corpo e, após a modificação, estou carregando o conteúdo novamente, mas não consigo ver o efeito da alteração da fonte imediatamente
— Ravi

13

eu fiz isso pelas respostas superiores com estas adições:

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

e então usar 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>" : "");
}


Obrigado a todos:)


Resposta perfeita !!
— SANAT de

6

Muitas das respostas acima funcionam perfeitamente se você tiver seu conteúdo na pasta de ativos.

No entanto, se quiser fazer o download e salvar todos os seus ativos de um servidor para o armazenamento interno, você pode usar loadDataWithBaseURLe usar uma referência para o armazenamento interno como baseUrl. Então, todos os arquivos serão relativos ao html carregado e serão encontrados e usados ​​corretamente.

No meu armazenamento interno, salvei os seguintes arquivos:

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

Então eu uso o seguinte código:

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

O arquivo CSS usado no html acima (style.css):

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

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

Eu só tentei fazer isso com o objetivo de minSdkVersion 19 (4.4), então não tenho ideia se funciona em outras versões


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
Melhore sua pergunta adicionando uma explicação do que você está fazendo.
— lifeisfoo

2

Você não precisa usar o arquivo ttf local para definir a fonte do webview para o Android. Isso aumentará o tamanho de todo o aplicativo.

você também pode usar fontes online como a fonte do google ... Isso ajudará a reduzir o tamanho do seu apk.

Por exemplo: visite o URL abaixo https://gist.github.com/karimnaaji/b6c9c9e819204113e9cabf290d580551#file-googlefonts-txt

Você encontrará as informações necessárias para usar esta fonte. em seguida, crie uma string como abaixo

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

então carregue o webview assim

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

feito. Você poderá carregar a fonte de uma fonte externa desta forma.

Agora, quanto à fonte do aplicativo, não faz sentido usar 1 fonte para o webview e uma fonte diferente para todo o aplicativo. Portanto, você pode usar fontes para download em seu aplicativo, que também usa fontes externas para carregar fontes no aplicativo.


1

Você pode fazer isso usando CSS. Fiz isso com um aplicativo, mas não funciona no Android 2.1, pois há um bug conhecido no navegador Android 2.1.


1

O problema é que ela precisa estar em uma pasta, tente colocar "./myfont.ttf" em vez disso, se não colocar a fonte dentro de uma pasta em recursos como "fonts / myfont.ttf" que funcionará com certeza.


0

teste, funcione para mim como um encanto:

   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

Se você estiver colocando fontes res/fontcomo eu, você pode alterar o diretório para o seguinte: -

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

0

Use a biblioteca https://github.com/delight-im/Android-AdvancedWebView .

em dados 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>

em xml:

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

em java:

advancedWebView = findViewById(R.id.advanced_web_view);
advancedWebView.loadHtml(htmlData, "text/html; charset=utf-8", "utf-8");

-3

É assim que você carrega htmlData em um webview:

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

onde getHtmlData(activity,**htmlData**)retorna uma string de código html.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.