Cuando usamos el componente
WebView de android, cargar fuentes personalizadas puede ser un pequeño infierno. Vamos a ver un ejemplo de como podemos cargar customs fonts en el navegador de android.
Para este ejemplo se han usado las siguientes tecnologías
- Mac OsX El capitan
- Android Studio 1.5
- JDK 1.8.0_65
Project ejemplo
Para ver como podemos añadir custom fonts a nuestro
WebView vamos a crear un proyecto de ejemplo, para ello pulsamos
File -> New -> Project en
AndroidStudio
A continuación elegimos la API target de android y el tipo de dispositivos que queremos cubrir, en nuestro caso solo
phones y tablets
Ahora elegimos un proyecto vacío
A continuación le damos un nombre a nuestra actividad inicial, en este ejemplo lo dejamos a como viene por defecto
Ahora ya tenemos nuestro proyecto listo.
Pagina a mostrar
Ahora que tenemos nuestro proyecto listo, añadimos al fichero
res/layout/content_main.xml un objeto webView
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.example.fhernandez.webviewcustomfontsexample.MainActivity"
tools:showIn="@layout/activity_main">
<WebView
android:layout_width="fill_parent"
android:layout_height="400dp"
android:id="@+id/myBowser"
android:layout_marginTop="10dp" />
</RelativeLayout>
Vamos a definir una pagina HTML estática que será completada dinámicamente en el código dentro de la carpeta de recursos
raw de android. Por defecto esta carpeta no se añade al proyecto, para añadirla hacemos doble click sobre el proyecto y pulsamos
New -> Android resource directory
A continuación seleccionamos raw
Al hacer esto se nos ha creado la carpeta
raw dentro de resources en el proyecto. Dentro de ella creamos un fichero llamado
our_page.html y le añadimos el siguiente contenido
<html>
<head>
<style>
@font-face {
font-family: "AppleGaramond";
src: url("fonts/AppleGaramond.ttf");
font-style: normal;
font-weight: normal;
}
@font-face {
font-family: "AppleGaramond";
src: url("fonts/AppleGaramond-Bold.ttf");
font-style: normal;
font-weight: bold;
}
* {font-family: 'AppleGaramond' !important;}
</style>
</head>
<body>
Hello to all, this is a <b>bold</b> text<br>
Como se puede observar, estamos definiendo nuestras fuentes en los estilos de la páginas y se lo aplicamos a todo la página.
Añadir custom fonts
Para añadir nuestras fuentes lo haremos añadiendo los ficheros al directorio
assets.
AndroidStudio no añade este directorio por defecto en el proyecto, para añadirlo hacemos doble click sobre el proyecto y pulsamos
New -> Folder -> Assets Folder
En la siguiente ventana confirmamos
Ahora tendremos el directorio
assets disponible, creamos dentro de él un directorio llamado
fonts y copiamos ahi nuestro archivos de fuentes. Nuestro proyecto queda de la siguiente manera
Cargamos nuestra página en el webview
Vamos a modificar la actividad principal para cargar nuestra pagina, para ello el código quedara asi
package com.example.fhernandez.webviewcustomfontsexample;
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.webkit.WebView;
import java.io.IOException;
import java.io.InputStream;
public class MainActivity extends AppCompatActivity {
private WebView myBowser;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
myBowser = (WebView) findViewById(R.id.myBowser);
// Load our page
loadData();
}
private void loadData() {
// read the file
String myPage = "";
try {
myPage = getStringFromFile(this, R.raw.our_page);
} catch (IOException e) {
e.printStackTrace();
}
// Complete the page
myPage = myPage + "This is a part added from code <b>awesome!</b></body></html>";
myBowser.loadData(myPage, "text/html; charset=UTF-8", null);
}
// Read from res/raw
public String getStringFromFile (Context context, int resId) throws IOException {
String result;
Resources res = context.getResources();
InputStream in_s = res.openRawResource(resId);
byte[] b = new byte[in_s.available()];
in_s.read(b);
result = new String(b);
return result;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Resultado
Ahora que ya tenemos nuestro proyecto listo, ejecutamos nuestra aplicación y veremos lo siguiente
El resultado no es
correcto, ya que se
NO se están usando nuestras fuentes.
Corregir el uso de custom fonts
Para que el navegador pueda cargar nuestras fuentes debemos modificar la forma en que se carga la página y hacerlo de esta forma
myBowser.loadDataWithBaseURL("file:///android_asset/", myPage, "text/html", "utf-8",null);
Ahora, si ejecutamos de nuevo, veremos que carga nuestra fuente correctamente
Puedes descargar el código de este ejemplo desde
github