web-dev-qa-db-fra.com

Comment changer la police de Webview dans Android?

Je veux changer la police par défaut de webview en une police personnalisée. J'utilise WebView pour développer une application de navigateur bilingue pour Android.

J'ai essayé d'obtenir une instance de police personnalisée en plaçant ma police personnalisée dans des éléments. Mais je ne pouvais toujours pas définir la police par défaut de Webview sur ma police.

C'est ce que j'ai essayé:

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

Est-ce que quelqu'un peut corriger cela ou suggérer une autre méthode pour changer la police par défaut de Webview en une police personnalisée?

Merci!

93
Dhanika

Il existe un exemple de travail dans ce projet . Cela revient à:

  1. Dans votre dossier assets/fonts, Placez la police OTF ou TTF souhaitée (ici MyFont.otf)
  2. Créez un fichier HTML que vous utiliserez pour le contenu de WebView, dans le dossier assets (ici dans 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. Chargez le code HTML dans la vue Web à partir du code:

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

Notez que l'injection de HTML via loadData() n'est pas autorisée. selon la documentation :

Notez que la même politique d'origine de JavaScript signifie que les scripts exécutés dans une page chargée à l'aide de cette méthode ne pourront pas accéder au contenu chargé à l'aide d'un schéma autre que "data", y compris "http (s)". Pour éviter cette restriction, utilisez loadDataWithBaseURL () avec une URL de base appropriée.

Comme @JaakL le suggère dans le commentaire ci-dessous, pour charger du HTML à partir d'une chaîne, vous devez plutôt fournir l'URL de base pointant vers vos actifs:

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

Lorsque vous faites référence à la police dans htmlData, vous pouvez simplement utiliser /fonts/MyFont.otf (En omettant l'URL de base).

104
Paul Lammertsma

J'utilise ce code:

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);
94
Omid Omidi

Encore plus simple, vous pouvez utiliser le format d’URL de l’actif pour référencer la police. Aucune programmation nécessaire!

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

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

...

49
Dan Syrstad

Cela peut être fait dans Android. J'ai pris trois jours pour résoudre ce problème. Mais maintenant, cela semble très facile. Suivez ces étapes pour définir une police personnalisée pour Webview.

1.Ajouter votre police au dossier des actifs
2.Copiez la police dans le répertoire de fichiers de l'application

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.Vous devez appeler la fonction ci-dessus une seule fois (vous devez trouver une logique pour cela).

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

4.Utilisez le code ci-dessous pour définir la valeur de votre vue Web. Ici, j'utilise CSS pour définir la police.

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.Vous pouvez appeler la fonction ci-dessus comme ci-dessous

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

je l'ai fait par réponses supérieures avec ces ajouts:

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

puis utilisez 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>" : "");
}


Merci à tout le monde:)

12
V. Kalyuzhnyu

La plupart des réponses ci-dessus fonctionnent si vous avez votre contenu dans votre dossier d'actifs.

Cependant, si vous voulez, vous souhaitez télécharger et enregistrer tous vos actifs d'un serveur sur votre stockage interne, vous pouvez utiliser plutôt loadDataWithBaseURL et utiliser une référence à votre stockage interne comme baseUrl. Ensuite, tous les fichiers seront relatifs au code HTML chargé et seront trouvés et utilisés correctement.

Dans mon stockage interne, j'ai sauvegardé les fichiers suivants:

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

Ensuite, j'utilise le code suivant:

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

Le fichier CSS utilisé dans le code HTML ci-dessus (style.css):

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

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

Je n'ai essayé que cela en ciblant minSdkVersion 19 (4.4), donc je ne sais pas si cela fonctionne sur d'autres versions.

5
lejonl
 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);
3
Suport Pfrproject

Le problème est qu’il doit se trouver dans un dossier. Essayez plutôt de placer "./myfont.ttf", sinon, placez la police dans un dossier dans des éléments tels que "fonts/myfont.ttf" qui fonctionnera à coup sûr.

1
schwiz

Vous pouvez le faire en utilisant CSS. Je l'ai fait avec une application mais cela ne fonctionnera pas dans Android 2.1 car il existe un bogue connu avec Android navigateur 2.1.

1
Jay Mayu

Vous n’avez pas besoin d’utiliser un fichier ttf local pour définir la police webview pour Android, cela augmentera la taille de l’application.

vous pouvez également utiliser des polices en ligne comme celle de google ... Cela vous aidera à réduire la taille de votre apk.

Par exemple: visitez l'URL ci-dessous https://Gist.github.com/karimnaaji/b6c9c9e819204113e9cabf290d580551#file-googlefonts-txt

Vous trouverez les informations nécessaires pour utiliser cette police. puis créez une chaîne comme ci-dessous

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

puis chargez la vue Web comme ceci

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

terminé. Vous pourrez charger la police à partir de la source externe de cette façon.

Maintenant, en ce qui concerne la police de l'application, il n'est pas logique d'utiliser 1 police pour l'affichage Web et une police différente pour l'application entière. Vous pouvez donc utiliser polices téléchargeables dans votre application, qui utilise également des sources externes pour le chargement des polices dans l'application.

0
Afjalur Rahman Rana