Jak zmienić krój czcionki Webview w systemie Android?


97

Chcę zmienić domyślną czcionkę widoku internetowego na czcionkę niestandardową. Używam Webview do tworzenia dwujęzycznej przeglądarki na Androida.

Próbowałem uzyskać niestandardowy krój, umieszczając moją niestandardową czcionkę w zasobach. Ale nadal nie mogłem ustawić domyślnej czcionki Webview na moją czcionkę.

Oto, czego próbowałem:

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

Czy ktoś może to poprawić lub zasugerować inną metodę zmiany domyślnej czcionki Webview na niestandardową czcionkę?

Dzięki!


W końcu zdałem sobie sprawę, że nie da się tego zrobić.
Dhanika


cześć, czy znalazłeś jakieś rozwiązanie dla tej rzeczy z czcionką, próbuję dla hindi font stackoverflow.com/q/5868198/501859 . pomóż mi, jeśli masz rozwiązanie
Kishore

@Dhanika, jak rozwiązać ten problem w obliczu tego samego problemu.
NagarjunaReddy

Odpowiedzi:


112

W tym projekcie jest działający przykład . Sprowadza się do:

  1. W swoim assets/fontsfolderze umieść żądaną czcionkę OTF lub TTF (tutaj MyFont.otf)
  2. Utwórz plik HTML, którego będziesz używać dla zawartości WebView, w assetsfolderze (tutaj w środku 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. Załaduj kod HTML do WebView z kodu:

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

Zwróć uwagę, że wstrzykiwanie kodu HTML przez loadData()nie jest dozwolone. Zgodnie z dokumentacją :

Należy pamiętać, że zasada tego samego pochodzenia JavaScript oznacza, że ​​skrypt działający na stronie załadowanej przy użyciu tej metody nie będzie mógł uzyskać dostępu do treści załadowanej przy użyciu innego schematu niż „dane”, w tym „http (s)”. Aby uniknąć tego ograniczenia, użyj funkcji loadDataWithBaseURL () z odpowiednim podstawowym adresem URL.

Jak @JaakL sugeruje w poniższym komentarzu, aby załadować kod HTML z ciągu znaków, należy zamiast tego podać podstawowy adres URL wskazujący na zasoby:

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

Odwołując się do czcionki w htmlData, możesz po prostu użyć /fonts/MyFont.otf(pomijając podstawowy adres URL).


10
LoadData () nie działa, ale webView.loadDataWithBaseURL ("file: /// android_asset /", ... działa dobrze. Wtedy też powinno działać odwołanie do pliku czcionki jako "/fonts/MyFont.otf".
JaakL

W moim przypadku dane wracają w postaci tagów z edytora ck (backend api) <div style = \ "text-align: center; \"> <span style = \ "background-color: transparent; \"> < kolor czcionki = \ "# f20505 \" size = \ "5 \" face = \ "Comic Sans MS \"> Podziel się z nami swoją opinią <\ / font> <\ / span> Ustawiam to jako webview.loadData () ale nie bierze czcionek, jakieś rozwiązanie?
B.shruti

Comic Sans MS nie jest czcionką dostarczaną przez Androida. Będzie działać tylko wtedy, gdy zdefiniujesz krój czcionki w CSS i dostarczysz plik czcionki w zasobach aplikacji.
Paul Lammertsma

2
moja czcionka znajduje się w res/fontfolderze. Jaka byłaby wtedy ścieżka? Próbowałem, file:///android_res/font/ale to nie działa.
Wirling

105

Używam tego kodu :

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
O MÓJ BOŻE! To jest dokładnie to, co nas poprowadziło na trop tego, co poszło nie tak: jak się okazuje, Android 4.2 NIE renderuje czcionki, jeśli dodasz „format ('ttf')” za „src: url ('... „)”. Zostaw to, a czcionki będą pięknie renderowane. Przetestowano przy użyciu własnych czcionek internetowych Google.
Pascal Lindelauf

2
To bujające rozwiązanie, Kciuki w górę
Saad Bilal

loadDataWithBaseURL nie działa na Androidzie 4.1 i 4.2 :(
Misha Akopov

nie działa dla mnie w systemie Android 5.1. Skorzystałem z odpowiedzi (Dana Syrstada). różnica polega na notowaniufont-family: 'myface';
Mneckoee

52

Jeszcze prościej, możesz użyć formatu adresu URL zasobu, aby odwołać się do czcionki. Bez programowania!

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

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

...


1
Jeśli umieszczę plik .ttfi .htmlw tym samym katalogu i załaduję go w przeglądarce Androida, działa. Jednak w WebView mojej aplikacji, podczas gdy CSS pokazuje, tekst pojawia się w domyślnej czcionce Androida pomimo dodania .ttfdo assets/fontsfolderu projektu . Testuję na 2.3.5, ale buduję na 2.1. Czy to może być problem, czy czegoś mi brakuje?
Paul Lammertsma

1
Znalazłem rozwiązanie: jeśli tworzysz plik HTML i umieszczasz go w zasobach, ładujesz go za pośrednictwem view.loadUrl()dzieł, a view.loadData()nie. Nie mam pojęcia, dlaczego ten drugi nie.
Paul Lammertsma

4
Lil 'późno, ale działa z view.loadDataWithBaseUrl (null, content, mime, enconding, null)
Ours

28

Można to zrobić w systemie Android. Rozwiązanie tego problemu zajęło mi trzy dni. Ale teraz wydaje się to bardzo łatwe. Wykonaj poniższe czynności, aby ustawić niestandardową czcionkę dla Webview

1. Dodaj czcionkę do folderu zasobów 2.
Skopiuj czcionkę do katalogu plików aplikacji

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. Powyższą funkcję musisz wywołać tylko raz (musisz znaleźć do tego jakąś logikę).

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

4. Użyj poniższego kodu, aby ustawić wartość widoku internetowego. Tutaj używam CSS, aby ustawić czcionkę.

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. Możesz wywołać powyższą funkcję jak poniżej

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

Cześć! Próbowałem tego podejścia, ale WebView nadal nie ładuje mojej czcionki. Czy zrobiłeś coś specjalnego? Dzięki!
Zarah,

jak to zrobić dla html stackoverflow.com/q/5868198/501859 . pomóż mi, jeśli masz rozwiązanie
Kishore

U mnie to działa. Dzięki Binary.
Ravi Shanker Yadav

Mam ten czcionki w folderze aktywów i zmiany css z tego pełną ścieżkę czcionkę i nazwiska w organizmie, a po modyfikacji znów jestem ładowanie treści, ale może „t natychmiast zobaczyć efekt zmiany czcionki
Ravi

13

zrobiłem to przez górne odpowiedzi z następującymi dodatkami:

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

a następnie użyj 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>" : "");
}


Dziękuję wszystkim:)


Doskonała odpowiedź !!
SANAT

6

Wiele z powyższych odpowiedzi działa, jeśli masz swoje treści w folderze zasobów.

Jeśli jednak chcesz, abym pobierał i zapisywał wszystkie swoje zasoby z serwera do pamięci wewnętrznej, możesz zamiast tego użyć loadDataWithBaseURLi użyć odniesienia do pamięci wewnętrznej jako baseUrl. Wtedy wszystkie pliki będą zależne od załadowanego html i zostaną znalezione i użyte poprawnie.

W mojej pamięci wewnętrznej zapisałem następujące pliki:

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

Następnie używam następującego kodu:

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

Plik CSS użyty w powyższym html (style.css):

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

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

Próbowałem tego tylko podczas kierowania na minSdkVersion 19 (4.4), więc nie mam pojęcia, czy działa na innych wersjach


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
Popraw swoje pytanie, dodając wyjaśnienie, co robisz.
lifeisfoo

2

Nie musisz używać lokalnego pliku ttf, aby ustawić czcionkę widoku internetowego dla Androida, zwiększy to cały rozmiar aplikacji.

możesz także używać czcionek internetowych, takich jak czcionka Google ... Pomoże to zmniejszyć rozmiar pliku APK.

Na przykład: odwiedź poniższy adres URL https://gist.github.com/karimnaaji/b6c9c9e819204113e9cabf290d580551#file-googlefonts-txt

Znajdziesz niezbędne informacje, aby użyć tej czcionki. następnie utwórz ciąg jak poniżej

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

następnie załaduj widok sieciowy w ten sposób

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

Gotowe. W ten sposób będziesz mógł załadować czcionkę z zewnętrznego źródła.

A co z czcionką aplikacji, nie ma sensu używać jednej czcionki dla widoku internetowego i innej czcionki dla całej aplikacji. Możesz więc używać czcionek do pobrania w swojej aplikacji, która również korzysta z zewnętrznych źródeł do ładowania czcionek w aplikacji.


1

Możesz to zrobić za pomocą CSS. Zrobiłem to z aplikacją, ale nie będzie działać w systemie Android 2.1, ponieważ jest znany błąd w przeglądarce Androida 2.1.


1

Problem polega na tym, że musi znajdować się w folderze, spróbuj zamiast tego wstawić „./myfont.ttf”, jeśli nie, umieść czcionkę w folderze w zasobach takich jak „fonts / myfont.ttf”, które na pewno zadziałają.


0

przetestuj to, pracuj dla mnie jak urok:

   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

Jeśli umieszczasz czcionki pod res/fonttakimi jak ja, możesz zmienić katalog na następujący: -

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

0

Użyj biblioteki https://github.com/delight-im/Android-AdvancedWebView .

w danych 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>

w xml:

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

w java:

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

-3

Oto jak ładujesz htmlData w widoku internetowym:

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

gdzie getHtmlData(activity,**htmlData**)zwraca ciąg kodu html.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.