Wie ändere ich die Schriftart von Webview in Android?

97

Ich möchte die Standardschriftart von Webview in eine benutzerdefinierte Schriftart ändern. Ich verwende Webview bei der Entwicklung einer zweisprachigen Browser-App für Android.

Ich habe versucht, eine Instanz einer benutzerdefinierten Schriftart zu erhalten, indem ich meine benutzerdefinierte Schriftart in Assets platziert habe. Die Standardschriftart von Webview konnte jedoch immer noch nicht auf meine Schriftart eingestellt werden.

Folgendes habe ich versucht:

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

Kann jemand dies korrigieren oder eine andere Methode vorschlagen, um die Standardschriftart von Webview in eine benutzerdefinierte Schriftart zu ändern?

Vielen Dank!

Dhanika
quelle
Schließlich wurde mir klar, dass dies nicht möglich ist.
Dhanika
Schau dir das an. stackoverflow.com/questions/1344080/…
Samuel
Hallo, hast du eine Lösung für diese Schriftart gefunden ? Ich versuche für Hindi-Schriftarten stackoverflow.com/q/5868198/501859 . Hilf mir, wenn du die Lösung hast
Kishore
@Dhanika, wie man dieses Problem mit dem gleichen Problem löst.
NagarjunaReddy
Unter diesem Link finden Sie Informationen zum Festlegen der benutzerdefinierten Schriftart im Webview-Text. Stackoverflow.com/a/25692052/3921740[1] [1]: stackoverflow.com/a/25692052/3921740
user3921740

Antworten:

111

In diesem Projekt gibt es ein funktionierendes Beispiel dafür . Es läuft darauf hinaus:

  1. assets/fontsPlatzieren Sie in Ihrem Ordner die gewünschte OTF- oder TTF-Schriftart (hier MyFont.otf).
  2. Erstellen Sie eine HTML-Datei, die Sie für den Inhalt von WebView verwenden, im assetsOrdner (hier im Inneren 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. Laden Sie den HTML-Code aus dem Code in das WebView:

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

Beachten Sie, dass das Einfügen des HTML-Codes loadData()nicht zulässig ist. Gemäß Dokumentation :

Beachten Sie, dass die gleiche Ursprungsrichtlinie von JavaScript bedeutet, dass Skripte, die auf einer mit dieser Methode geladenen Seite ausgeführt werden, nicht auf Inhalte zugreifen können, die mit einem anderen Schema als "Daten" geladen wurden, einschließlich "http (s)". Um diese Einschränkung zu vermeiden, verwenden Sie loadDataWithBaseURL () mit einer geeigneten Basis-URL.

Wie @JaakL im folgenden Kommentar vorschlägt, sollten Sie zum Laden von HTML aus einer Zeichenfolge stattdessen die Basis-URL angeben, die auf Ihre Assets verweist:

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

Wenn Sie auf die Schriftart verweisen htmlData, können Sie diese einfach verwenden /fonts/MyFont.otf(ohne die Basis-URL).

Paul Lammertsma
quelle
10
LoadData () funktioniert nicht, aber webView.loadDataWithBaseURL ("file: /// android_asset /", ... funktioniert einwandfrei. Dann sollte auch die Referenz der Schriftdatei als "/fonts/MyFont.otf" funktionieren.
JaakL
In meinem Fall werden Daten in Form von Tags vom ck-Editor (Backend-API) zurückgegeben. <Div style = "text-align: center;"> <span style = "background-color: transparent;"> < font color = "# f20505" size = "5" face = "Comic Sans MS" Bitte teilen Sie uns Ihr Feedback mit. <\ / font> <\ / span> Ich setze es als webview.loadData () aber es nimmt keine Schriftarten, Irgendeine Lösung?
B. Shruti
Comic Sans MS ist keine von Android bereitgestellte Schriftart. Dies funktioniert nur, wenn Sie die Schriftart in CSS definiert und die Schriftartdatei in den Assets Ihrer Anwendung bereitgestellt haben.
Paul Lammertsma
2
Meine Schriftart befindet sich im res/fontOrdner. Was wäre dann der Weg? Ich habe es versucht, file:///android_res/font/aber es scheint nicht zu funktionieren.
Wirling
105

Ich benutze diesen 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
quelle
2
OH MEIN GOTT! Genau das hat uns auf die Spur gebracht, was schief gelaufen ist: Wie sich herausstellt, rendert Android 4.2 die Schriftart NICHT, wenn Sie das "Format ('ttf')" hinter "src: url ('... ') "Klausel. Lassen Sie das weg und die Schriftarten werden wunderschön gerendert. Getestet mit Googles eigenen Web-Schriftarten.
Pascal Lindelauf
2
Dies ist eine rockige Lösung, Daumen hoch
Saad Bilal
loadDataWithBaseURL funktioniert nicht auf Android 4.1 und 4.2 Versionen :(
Misha Akopov
hat bei mir in android 5.1 nicht funktioniert. Ich habe die Antwort von (Dan Syrstad) verwendet. Der Unterschied ist Zitatfont-family: 'myface';
Mneckoee
52

Noch einfacher ist es, das Asset-URL-Format zu verwenden, um auf die Schriftart zu verweisen. Keine Programmierung erforderlich!

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

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

...

Dan Syrstad
quelle
1
Wenn ich die .ttfund .html-Datei in dasselbe Verzeichnis lege und sie im Android-Browser lade, funktioniert es. In der WebView meiner App wird der Text, während das CSS angezeigt wird, in der Standardschriftart von Android angezeigt, obwohl er dem Ordner .ttfdes Projekts hinzugefügt wurde assets/fonts. Ich teste auf 2.3.5, baue aber gegen 2.1. Könnte das das Problem sein, oder fehlt mir etwas?
Paul Lammertsma
1
Ich habe eine Lösung gefunden: Wenn Sie eine HTML-Datei erstellen und in den Assets platzieren, laden Sie sie über view.loadUrl()Works, während view.loadData()dies nicht der Fall ist. Ich habe keine Ahnung, warum letzteres nicht.
Paul Lammertsma
4
Ein bisschen spät, aber es funktioniert mit view.loadDataWithBaseUrl (null, content, mime, enconding, null)
Unsere
28

Dies kann in Android erfolgen. Ich habe drei Tage gebraucht, um dieses Problem zu lösen. Aber jetzt scheint es sehr einfach. Führen Sie die folgenden Schritte aus, um die benutzerdefinierte Schriftart für Webview festzulegen

1. Fügen Sie Ihre Schriftart zum Ordner "Assets" hinzu.
2. Kopieren Sie die Schriftart in das Dateiverzeichnis der Anwendung

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. Sie müssen die obige Funktion nur einmal aufrufen (Sie müssen eine Logik dafür finden).

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

4.Verwenden Sie den folgenden Code, um den Wert für Ihre Webansicht festzulegen. Hier verwende ich CSS, um die Schriftart festzulegen.

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.Sie können die obige Funktion wie folgt aufrufen

webview.loadDataWithBaseURL(null, getHtmlData(activity,htmlData) , "text/html", "utf-8", "about:blank");
binär
quelle
Hallo! Ich habe diesen Ansatz ausprobiert, aber das WebView lädt meine Schriftart immer noch nicht. Gibt es etwas Besonderes, das du getan hast? Vielen Dank!
Zarah
Wie geht das für HTML Stackoverflow.com/q/5868198/501859 . Hilf mir, wenn du die Lösung hast
Kishore
Es funktioniert für mich. Danke Binary.
Ravi Shanker Yadav
Ich habe die Schriftart im Asset-Ordner und ändere CSS mit dem vollständigen Pfad der Schriftart und des Schriftfamiliennamens im Hauptteil. Nach der Änderung lade ich den Inhalt erneut, kann aber den Effekt der Schriftartenänderung nicht sofort sehen
Ravi
13

Ich tat dies durch obere Antworten mit diesen Ergänzungen:

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

und dann verwenden 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>" : "");
}


Danke an Alle:)

Vlad
quelle
Perfekte Antwort!!
SANAT
6

Viele der oben genannten Antworten funktionieren, wenn Sie Ihren Inhalt in Ihrem Assets-Ordner haben.

Wenn Sie jedoch möchten, dass ich alle Ihre Assets von einem Server in Ihren internen Speicher herunterlade und speichere, können Sie stattdessen loadDataWithBaseURLeinen Verweis auf Ihren internen Speicher als baseUrl verwenden. Dann sind alle Dateien dort relativ zum geladenen HTML und werden gefunden und korrekt verwendet.

In meinem internen Speicher habe ich folgende Dateien gespeichert:

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

Dann benutze ich folgenden Code:

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

Die im obigen HTML-Code (style.css) verwendete CSS-Datei:

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

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

Ich habe dies nur beim Targeting von minSdkVersion 19 (4.4) versucht, daher habe ich keine Ahnung, ob es auf anderen Versionen funktioniert

lejonl
quelle
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);
Unterstützen Sie das Projekt
quelle
2
Bitte verbessern Sie Ihre Frage und fügen Sie eine Erklärung hinzu, was Sie tun.
Lifeisfoo
2

Sie müssen keine lokale ttf-Datei verwenden, um die Webview-Schriftart für Android festzulegen. Dadurch wird die gesamte App-Größe erhöht.

Sie können auch Online-Schriftarten wie die Schriftart von Google verwenden ... Dies hilft Ihnen, Ihre Apk-Größe zu reduzieren.

Beispiel: Besuchen Sie die folgende URL: https://gist.github.com/karimnaaji/b6c9c9e819204113e9cabf290d580551#file-googlefonts-txt

Sie finden die notwendigen Informationen, um diese Schriftart zu verwenden. Erstellen Sie dann einen String wie unten

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

Laden Sie dann die Webansicht wie folgt

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

getan. Auf diese Weise können Sie die Schriftart von der externen Quelle laden.

Was ist nun mit der App-Schriftart? Es ist nicht sinnvoll, 1 Schriftart für die Webansicht und eine andere Schriftart für die gesamte App zu verwenden. Sie können also herunterladbare Schriftarten in Ihrer App verwenden, die auch externe Quellen zum Laden von Schriftarten in die App verwendet.

Afjalur Rahman Rana
quelle
1

Sie können dies mithilfe von CSS tun. Ich habe es mit einer App gemacht, aber es funktioniert nicht in Android 2.1, da es einen bekannten Fehler mit Android Browser 2.1 gibt.

Mayu Mayooresan
quelle
1

Das Problem ist, dass es sich in einem Ordner befinden muss. Versuchen Sie stattdessen, "./myfont.ttf" einzufügen. Wenn Sie die Schriftart nicht in einem Ordner in Assets wie "fonts / myfont.ttf" ablegen, funktioniert dies mit Sicherheit.

Nathan Schwermann
quelle
0

teste es, arbeite für mich wie ein Zauber:

   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
quelle
0

Wenn Sie Schriftarten res/fontwie ich unterlegen , können Sie das Verzeichnis wie folgt ändern: -

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

Verwenden Sie die Bibliothek https://github.com/delight-im/Android-AdvancedWebView .

in HTML-Daten:

<!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>

in xml:

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

in Java:

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

So laden Sie htmlData in eine Webansicht:

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

Dabei wird getHtmlData(activity,**htmlData**)eine Zeichenfolge mit HTML-Code zurückgegeben.

Alex Aung
quelle