¿Cómo cambiar el tipo de letra de Webview en Android?


97

Quiero cambiar la fuente predeterminada de la vista web a una fuente personalizada. Estoy usando webview para desarrollar una aplicación de navegador bilingüe para Android.

Intenté obtener una instancia de tipografía personalizada colocando mi fuente personalizada en assets. Pero todavía no pude establecer la fuente predeterminada de webview en mi fuente.

Esto es lo que probé:

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

¿Alguien puede corregir esto o sugerir algún otro método para cambiar la fuente predeterminada de webview a una fuente personalizada?

¡Gracias!


Finalmente me di cuenta de que esto no se puede hacer.
Dhanika


hola, ¿encontró alguna solución para este aspecto de la fuente? Estoy tratando de obtener la fuente hindi stackoverflow.com/q/5868198/501859 . ayúdame si tienes la solución
Kishore

@Dhanika cómo resolver este problema frente al mismo problema.
NagarjunaReddy

Consulte este enlace para establecer una fuente personalizada en el texto de la vista web. Stackoverflow.com/a/25692052/3921740[1] [1]: stackoverflow.com/a/25692052/3921740
user3921740

Respuestas:


111

Hay un ejemplo práctico de esto en este proyecto . Se reduce a:

  1. En su assets/fontscarpeta, coloque la fuente OTF o TTF deseada (aquí MyFont.otf)
  2. Cree un archivo HTML que usará para el contenido de WebView, dentro de la assetscarpeta (aquí 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. Cargue el HTML en WebView desde el código:

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

Tenga en cuenta que loadData()no está permitido inyectar HTML . Según la documentación :

Tenga en cuenta que la misma política de origen de JavaScript significa que el script que se ejecuta en una página cargada con este método no podrá acceder al contenido cargado con ningún esquema que no sea 'datos', incluidos 'http (s)'. Para evitar esta restricción, use loadDataWithBaseURL () con una URL base adecuada.

Como sugiere @JaakL en el comentario a continuación, para cargar HTML desde una cadena, debe proporcionar la URL base que apunta a sus activos:

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

Cuando haga referencia a la fuente htmlData, simplemente puede usar /fonts/MyFont.otf(omitiendo la URL base).


10
LoadData () no funciona, pero webView.loadDataWithBaseURL ("file: /// android_asset /", ... funciona bien. Entonces también debería funcionar la referencia del archivo de fuente como "/fonts/MyFont.otf".
JaakL

En mi caso, los datos regresan en forma de etiquetas desde ck editor (backend api) <div style = \ "text-align: center; \"> <span style = \ "background-color: transparent; \"> < font color = \ "# f20505 \" size = \ "5 \" face = \ "Comic Sans MS \"> Comparta sus comentarios con nosotros <\ / font> <\ / span> Lo configuro como webview.loadData () pero no acepta fuentes, ¿alguna solución?
B.shruti

Comic Sans MS no es una fuente proporcionada por Android. Solo funcionará si ha definido el tipo de fuente en CSS y ha proporcionado el archivo de fuente en los activos de su aplicación.
Paul Lammertsma

2
mi fuente se encuentra en la res/fontcarpeta. ¿Cuál sería entonces el camino? Lo intenté file:///android_res/font/pero no parece funcionar.
Wirling

105

Estoy 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
¡DIOS MIO! ESTO es exactamente lo que nos puso en el camino de lo que estaba saliendo mal: resulta que Android 4.2 NO procesa la fuente si agrega el "formato ('ttf')" detrás de "src: url ('... ') "cláusula. Deja eso y las fuentes se renderizan maravillosamente. Probado con fuentes web propias de Google.
Pascal Lindelauf

2
Esta es una solución excelente, pulgares arriba
Saad Bilal

loadDataWithBaseURL no funciona en las versiones de Android 4.1 y 4.2 :(
Misha Akopov

no funcionó para mí en Android 5.1. Usé la respuesta de (Dan Syrstad). la diferencia es cotizaciónfont-family: 'myface';
Mneckoee

52

Aún más simple, puede usar el formato de URL de activos para hacer referencia a la fuente. ¡No se necesita programación!

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

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

...


1
Si coloco el archivo .ttfy .htmlen el mismo directorio y lo cargo en el navegador de Android, funciona. Sin embargo, en el WebView de mi aplicación, mientras se muestra el CSS, el texto aparece en la fuente predeterminada de Android a pesar de agregarlo .ttfa la assets/fontscarpeta del proyecto . Estoy probando en 2.3.5, pero construyendo contra 2.1. ¿Podría ser ese el problema o hay algo que me falta?
Paul Lammertsma

1
Encontré una resolución: si crea un archivo HTML y lo coloca en los activos, cargarlo a través de view.loadUrl()funciona, mientras view.loadData()que no. No tengo ni idea de por qué este último no lo hace.
Paul Lammertsma

4
Un poco tarde, pero funciona con view.loadDataWithBaseUrl (null, content, mime, enconding, null)
Nuestro

28

Se puede hacer en Android. Me tomó tres días resolver este problema. Pero ahora parece muy fácil. Siga estos pasos para configurar una fuente personalizada para Webview

1.Agregue su fuente a la carpeta de activos
2.Copie la fuente al directorio de archivos de la aplicación

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. Debe llamar a la función anterior solo una vez (debe encontrar algo de lógica para esto).

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

4.Utilice el siguiente código para establecer el valor de su vista web. Aquí estoy usando CSS para establecer la fuente.

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.Puede llamar a la función anterior como se muestra a continuación

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

¡Hola! Probé este enfoque pero WebView todavía no carga mi fuente. ¿Hiciste algo especial? ¡Gracias!
Zarah

cómo hacer eso para html stackoverflow.com/q/5868198/501859 . ayúdame si tienes la solución
Kishore

Funciona para mí Gracias Binary.
Ravi Shanker Yadav

Tengo la fuente en la carpeta de activos y cambio css con esa ruta completa de la fuente y el nombre de la familia de fuentes en el cuerpo, y después de la modificación, estoy cargando el contenido nuevamente pero no puedo ver el efecto de cambio de fuente inmediatamente
Ravi

13

Hice esto por respuestas superiores con estas adiciones:

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

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


Gracias a todos:)


¡¡Respuesta perfecta!!
SANAT

6

Muchas de las respuestas anteriores funcionan de maravilla si tiene su contenido en su carpeta de activos.

Sin embargo, si me gusta, desea descargar y guardar todos sus activos desde un servidor a su almacenamiento interno, en su lugar, puede usar loadDataWithBaseURLy usar una referencia a su almacenamiento interno como baseUrl. Entonces, todos los archivos serán relativos al html cargado y se encontrarán y usarán correctamente.

En mi almacenamiento interno he guardado los siguientes archivos:

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

Luego utilizo el siguiente 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", "");

El archivo CSS utilizado en el html anterior (style.css):

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

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

Solo probé esto mientras apuntaba a minSdkVersion 19 (4.4), así que no tengo idea de si funciona en otras versiones


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
Mejore su pregunta agregando una explicación de lo que está haciendo.
lifeisfoo

2

No necesita usar el archivo ttf local para configurar la fuente de vista web para Android, aumentará el tamaño completo de la aplicación.

también puede usar fuentes en línea como la fuente de Google ... Le ayudará a reducir el tamaño de su apk.

Por ejemplo: visite la siguiente URL https://gist.github.com/karimnaaji/b6c9c9e819204113e9cabf290d580551#file-googlefonts-txt

Encontrará la información necesaria para utilizar esta fuente. luego crea una cadena como la siguiente

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

luego cargue la vista web así

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

hecho. Podrá cargar la fuente desde la fuente externa de esta manera.

Ahora, ¿qué pasa con la fuente de la aplicación? No tiene sentido usar una fuente para la vista web y una fuente diferente para toda la aplicación. Por lo tanto, puede usar fuentes descargables en su aplicación, que también usa fuentes externas para cargar fuentes en la aplicación.


1

Puedes hacerlo usando CSS. Lo hice con una aplicación pero no funciona en Android 2.1 ya que hay un error conocido con el navegador de Android 2.1.


1

El problema es que debe estar en una carpeta, intente poner "./myfont.ttf" en su lugar, si no, coloque la fuente dentro de una carpeta en activos como "fonts / myfont.ttf" que funcionará con seguridad.


0

pruébalo, trabaja para mí como un 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

Si está colocando fuentes res/fontcomo yo, puede cambiar el directorio a lo siguiente: -

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

0

Utilice la biblioteca https://github.com/delight-im/Android-AdvancedWebView .

en datos 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>

en xml:

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

en java:

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

-3

Así es como se carga htmlData en una vista web:

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

donde getHtmlData(activity,**htmlData**)devuelve una cadena de código html.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.