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.