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!

Dhanika
fonte
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).

Paul Lammertsma
fonte
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);
Omid Omidi
fonte
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;

...

Dan Syrstad
fonte
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");
binário
fonte
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:)

Vlad
fonte
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

Lejonl
fonte
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);
Suport Pfrproject
fonte
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.

Afjalur Rahman Rana
fonte
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.

Mayu Mayooresan
fonte
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.

Nathan Schwermann
fonte
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);
    }
sana ebadi
fonte
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;
}
Ibrahim Ali
fonte
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");
Baixar Arman
fonte
-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.

Alex Aung
fonte