Comment changer le visage de la police de Webview dans Android?

97

Je veux changer la police par défaut de la vue Web 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 les actifs. Mais je n'ai toujours pas pu définir la police par défaut de Webview sur ma police.

Voici ce que j'ai essayé:

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

Quelqu'un peut-il corriger cela ou suggérer une autre méthode pour changer la police par défaut de la vue Web en une police personnalisée?

Merci!

Dhanika
la source
Finalement, j'ai réalisé que cela ne pouvait pas être fait.
Dhanika
salut avez-vous trouvé une solution pour cette chose de visage de police, j'essaie pour la police hindi stackoverflow.com/q/5868198/501859 . aidez-moi si vous avez la solution
Kishore
@Dhanika comment résoudre ce problème face au même problème.
NagarjunaReddy
Veuillez consulter ce lien pour définir une police personnalisée dans le texte de la vue Web. Stackoverflow.com/a/25692052/3921740[1] [1]: stackoverflow.com/a/25692052/3921740
user3921740

Réponses:

112

Il y a un exemple concret de cela dans ce projet . Cela se résume à:

  1. Dans votre assets/fontsdossier, 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 assetsdossier (ici à l'intérieur 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 HTML dans la WebView à partir du code:

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

Notez que l'injection du HTML loadData()n'est pas autorisée. Selon la documentation :

Notez que la même politique d'origine de JavaScript signifie que le script exécuté dans une page chargée à l'aide de cette méthode ne pourra pas accéder au contenu chargé en utilisant 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);

Lors du référencement de la police dans htmlData, vous pouvez alors simplement utiliser /fonts/MyFont.otf(en omettant l'URL de base).

Paul Lammertsma
la source
10
LoadData () ne fonctionne pas, mais webView.loadDataWithBaseURL ("file: /// android_asset /", ... fonctionne bien. Ensuite, la référence de fichier de police comme "/fonts/MyFont.otf" devrait fonctionner.
JaakL
Dans mon cas, les données retournent sous la forme de balises de l'éditeur ck (api du backend) <div style = \ "text-align: center; \"> <span style = \ "background-color: transparent; \"> < font color = \ "# f20505 \" size = \ "5 \" face = \ "Comic Sans MS \"> Veuillez nous faire part de vos commentaires <\ / font> <\ / span> Je le configure comme webview.loadData () mais il ne prend pas les polices, toute solution ??
B.shruti
Comic Sans MS n'est pas une police fournie par Android. Cela ne fonctionnera que si vous avez défini le visage de la police dans CSS et fourni le fichier de police dans les ressources de votre application.
Paul Lammertsma
2
ma police se trouve dans le res/fontdossier. Quel serait le chemin alors? J'ai essayé file:///android_res/font/mais cela ne semble pas fonctionner.
Wirling
105

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);
Omid Omidi
la source
2
OMG! C'est exactement ce qui nous a mis sur la piste de ce qui n'allait pas: en fait, Android 4.2 ne rend PAS la police si vous ajoutez le "format ('ttf')" derrière le "src: url ('... ') "clause. Laissez cela de côté et les polices sont magnifiquement rendues. Testé avec les propres polices Web de Google.
Pascal Lindelauf
2
C'est une solution à bascule, Thumbs up
Saad Bilal
loadDataWithBaseURL ne fonctionne pas sur les versions Android 4.1 et 4.2 :(
Misha Akopov
ne fonctionnait pas pour moi dans Android 5.1. J'ai utilisé la réponse de (Dan Syrstad). la différence est la citationfont-family: 'myface';
Mneckoee
52

Encore plus simple, vous pouvez utiliser le format URL de l'élément 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;

...

Dan Syrstad
la source
1
Si je place le fichier .ttfet .htmldans le même répertoire et le charge dans le navigateur Android, cela fonctionne. Cependant, dans WebView de mon application, alors que le CSS s'affiche, le texte apparaît dans la police par défaut d'Android malgré l'ajout .ttfde au assets/fontsdossier du projet . Je teste sur 2.3.5, mais je construis contre 2.1. Cela pourrait-il être le problème ou y a-t-il quelque chose qui me manque?
Paul Lammertsma le
1
J'ai trouvé une résolution: si vous créez un fichier HTML et le placez dans les actifs, le charger via view.loadUrl()fonctionne, alors que ce view.loadData()n'est pas le cas. Je n'ai aucune idée de pourquoi ce dernier ne le fait pas.
Paul Lammertsma le
4
Un peu tard, mais cela fonctionne avec view.loadDataWithBaseUrl (null, content, mime, enconding, null)
nôtre
28

Cela peut être fait sous Android. J'ai mis 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.Ajoutez votre police au dossier des actifs
2.Copiez la police dans le répertoire des 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");

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");
binaire
la source
Salut! J'ai essayé cette approche mais WebView ne charge toujours pas ma police. Avez-vous fait quelque chose de spécial? Merci!
Zarah
comment faire cela pour html stackoverflow.com/q/5868198/501859 . aidez-moi si vous avez la solution
Kishore
Cela fonctionne pour moi.Merci binaire.
Ravi Shanker Yadav
J'ai la police dans le dossier des actifs et je change le css avec ce chemin complet de la police et le nom de la famille de polices dans le corps, et après modification, je charge à nouveau le contenu mais je ne peux pas voir l'effet de changement de police immédiatement
Ravi
13

J'ai fait cela par des 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:)

Vlad
la source
Réponse parfaite !!
SANAT
6

La plupart des réponses ci-dessus fonctionnent comme un charme si vous avez votre contenu dans votre dossier de ressources.

Cependant, si vous voulez comme moi télécharger et enregistrer tous vos actifs d'un serveur vers votre stockage interne, vous pouvez à la place utiliser loadDataWithBaseURLet utiliser une référence à votre stockage interne comme baseUrl. Ensuite, tous les fichiers seront relatifs au html chargé et seront trouvés et utilisés correctement.

Dans ma mémoire interne, j'ai enregistré 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 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é cela qu'en ciblant minSdkVersion 19 (4.4) donc je n'ai aucune idée si cela fonctionne sur d'autres versions

lejonl
la source
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
la source
2
Veuillez améliorer votre question en ajoutant une explication de ce que vous faites.
lifeisfoo
2

Vous n'avez pas besoin d'utiliser le fichier ttf local pour définir la police de la vue Web pour Android, cela augmentera la taille de l'application.

vous pouvez également utiliser des polices en ligne comme la police 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 ainsi charger la police depuis la source externe.

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

Afjalur Rahman Rana
la source
1

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

Mayu Mayooresan
la source
1

Le problème est qu'il doit être dans un dossier, essayez de mettre "./myfont.ttf" à la place, sinon mettez la police dans un dossier dans des actifs comme "fonts / myfont.ttf" qui fonctionnera à coup sûr.

Nathan Schwermann
la source
0

testez-le, travaillez pour moi comme un charme:

   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
la source
0

Si vous mettez des polices sous res/fontcomme moi, vous pouvez changer le répertoire comme suit: -

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

Utilisez la bibliothèque https://github.com/delight-im/Android-AdvancedWebView .

dans les données 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");
Télécharger Arman
la source
-3

Voici comment charger htmlData dans une vue Web:

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

getHtmlData(activity,**htmlData**)renvoie une chaîne de code html.

Alex Aung
la source