Як змінити обличчя шрифту Webview в Android?


97

Я хочу змінити шрифт веб-перегляду за замовчуванням на спеціальний шрифт. Я використовую веб-перегляд для розробки двомовної програми для браузера для Android.

Я спробував отримати екземпляр нестандартного шрифту, розмістивши свій власний шрифт в активах. Але все ще не вдалося встановити шрифт за замовчуванням веб-перегляду для мого шрифту.

Це те, що я спробував:

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

Чи може хтось виправити це чи запропонувати будь-який інший метод змінити шрифт за замовчуванням веб-перегляду на спеціальний шрифт?

Дякую!


Нарешті я зрозумів, що цього зробити не можна.
Dhanika


привіт, ти знайшов рішення для цієї штуки шрифту, я намагаюся для шрифту хінді stackoverflow.com/q/5868198/501859 . допоможи мені, якщо ти отримав рішення
Kishore

@Dhanika, як вирішити цю проблему, що стикається з тією ж проблемою.
NagarjunaReddy

Будь ласка , зверніться по цьому посиланню для безлічі користувальницьких шрифтів в тексті Webview .. stackoverflow.com/a/25692052/3921740[1] [1]: stackoverflow.com/a/25692052/3921740
user3921740

Відповіді:


111

У цьому проекті є робочий приклад цього . Він зводиться до:

  1. assets/fontsПомістіть у своїй папці потрібний шрифт OTF або TTF (тут MyFont.otf)
  2. Створіть файл HTML, який ви будете використовувати для вмісту WebView, всередині assetsпапки (тут всередині 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. Завантажте HTML у веб-перегляд із коду:

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

Врахуйте, що вводити HTML через loadData()не дозволяється. Відповідно до документації :

Зауважте, що та сама політика щодо джерела JavaScript означає, що сценарій, запущений на сторінці, завантаженій цим методом, не зможе отримати доступ до контенту, завантаженого за допомогою будь-якої схеми, окрім "даних", включаючи "http (s)". Щоб уникнути цього обмеження, використовуйте loadDataWithBaseURL () з відповідною базовою URL-адресою.

Як @JaakL пропонує в коментарі нижче, для завантаження HTML із рядка вам слід надати базову URL-адресу, що вказує на ваші активи:

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

Посилаючись на шрифт htmlData, ви можете просто використовувати /fonts/MyFont.otf(опустивши основну URL-адресу).


10
LoadData () не працює, але webView.loadDataWithBaseURL ("файл: /// android_asset /", ... працює нормально. Тоді також має працювати посилання на файл шрифту як "/fonts/MyFont.otf".
JaakL

У моєму випадку дані повертаються у вигляді тегів редактора ck (бекенд api) <div style = \ "text-align: center; \"> <span style = \ "background-color: transparent; \"> < font color = \ "# f20505 \" size = \ "5 \" face = \ "Comic Sans MS \"> Будь ласка, поділіться своїми відгуками з нами <\ / font> <\ / span> Я встановлюю її як webview.loadData () але його не беруть шрифти, будь-яке рішення ??
Б.Шруті

Comic Sans MS - це не шрифт, який надає Android. Він працюватиме лише в тому випадку, якщо ви визначили обличчя шрифту в CSS та надали файл шрифту в активах програми.
Пол

2
мій шрифт розташований у res/fontпапці. Якою була б тоді стежка? Я намагався, file:///android_res/font/але, здається, це не працює.
Wirling

105

Я використовую цей код :

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
О БОЖЕ МІЙ! Це саме те, що поставило нас на слід того, що пішло не так: як виявляється, Android 4.2 НЕ відображає шрифт, якщо ви додасте "format ('ttf") "за" src: url (' ... ') "пункт. Залиште це, а шрифти візуалізуються красиво. Тестується за допомогою власних веб-шрифтів Google.
Паскаль Лінделауф

2
Це хитне рішення, "Великі пальці вгору"
Саад Білал

loadDataWithBaseURL не працює на версіях Android 4.1 та 4.2 :(
Міша Акопов

не працював для мене в android 5.1. Я використав відповідь (Dan Syrstad). різниця - котируванняfont-family: 'myface';
Mneckoee

52

Навіть простіше, ви можете використовувати формат URL-адреси активів для посилання на шрифт. Не потрібно програмування!

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

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

...


1
Якщо я розміщу файл .ttfі .htmlв одному каталозі і завантажую його в браузер Android, це працює. Однак у веб-перегляді мого додатка під час показу CSS текст відображається шрифтом за замовчуванням Android, незважаючи на додавання .ttfдо assets/fontsпапки проекту . Я тестую на 2.3.5, але будую проти 2.1. Чи може це бути проблемою, чи щось мені не вистачає?
Пол Ламмерцма

1
Я знайшов дозвіл: якщо ви створите файл HTML і помістите його в об’єкти, завантажуючи його через view.loadUrl()твори, тоді як view.loadData()ні. Я не маю поняття, чому останній цього не робить.
Пол Ламмерцма

4
Lil 'пізно, але це працює з view.loadDataWithBaseUrl (null, content, mime, enconding, null)
Наш

28

Це можна зробити в Android. На вирішення цього питання мені знадобилося три дні. Але зараз це здається дуже легким. Виконайте ці дії, щоб встановити спеціальний шрифт для веб-перегляду

1.Додайте шрифт до папки активів 2.
Скопіюйте шрифт до каталогу файлів програми

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. Вам потрібно зателефонувати вищезгаданій функції лише один раз (для цього потрібно знайти певну логіку).

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

4. Використовуйте наведений нижче код, щоб встановити значення для веб-перегляду. Тут я використовую CSS для встановлення шрифту.

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.Ви можете вказати вищевказану функцію, як показано нижче

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

Привіт! Я спробував такий підхід, але WebView все ще не завантажує мій шрифт. Ви щось особливе зробили? Дякую!
Зара,

як це зробити для html stackoverflow.com/q/5868198/501859 . допоможіть мені, якщо у вас є рішення
Kishore

Це працює для мене. Дякую Binary.
Раві Шанкер Ядав

у мене є шрифт у папці ресурсів і змінюється css з цим повним шляхом імені шрифту та прізвища шрифтів у тілі, і після модифікації я знову завантажую вміст, але не можу побачити ефект зміни шрифту негайно
Ravi

13

я зробив це за верхніми відповідями з цими доповненнями:

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

а потім використовувати 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>" : "");
}


спасибі всім :)


Ідеальний відповідь !!
SANAT

6

Багато з наведених вище відповідей працюють привабливо, якщо ваш вміст знаходиться в папці ваших активів.

Однак, якщо ви подобаєтесь мені, ви хочете завантажити та зберегти всі свої ресурси із сервера на внутрішню пам’ять, ви можете замість цього використовувати loadDataWithBaseURLі використовувати посилання на свою внутрішню пам’ять як baseUrl. Тоді всі файли там будуть відносно завантаженого html і знайдені та використані правильно.

У внутрішній пам’яті я зберег наступні файли:

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

Тоді я використовую такий код:

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

Файл CSS, використаний у наведеному вище HTML (style.css):

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

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

Я лише спробував це, орієнтуючись на minSdkVersion 19 (4.4), тому я не маю уявлення, чи працює він в інших версіях


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
Будь ласка, вдосконаліть своє запитання, додавши пояснення того, що ви робите.
lifeisfoo

2

Вам не потрібно використовувати локальний файл ttf для встановлення шрифту веб-перегляду для android, це збільшить весь розмір програми.

ви також можете використовувати онлайн-шрифти, наприклад, шрифт google ... Це допоможе зменшити розмір apk.

Наприклад: відвідайте URL-адресу нижче https://gist.github.com/karimnaaji/b6c9c9e819204113e9cabf290d580551#file-googlefonts-txt

Ви знайдете необхідну інформацію для використання цього шрифту. потім створіть рядок, як показано нижче

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

потім завантажте веб-перегляд таким чином

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

зроблено. Ви зможете завантажити шрифт із зовнішнього джерела таким чином.

Що ж стосується шрифту програми, немає сенсу використовувати 1 шрифт для веб-перегляду та інший шрифт для всієї програми. Таким чином, ви можете використовувати завантажувані шрифти у своїй програмі, яка також використовує зовнішні джерела для завантаження шрифтів у програмі.


1

Ви можете зробити це за допомогою CSS. Я зробив це з додатком, але він не буде працювати в Android 2.1, оскільки існує відома помилка в браузері Android 2.1.


1

Проблема полягає в тому, що потрібно знаходитись у папці, спробуйте вставити "./myfont.ttf", якщо не вставити шрифт всередину папки в активах типу "шрифти / myfont.ttf", які точно працюватимуть.


0

протестуйте, працюйте для мене, як шарм:

   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

Якщо ви розміщуєте шрифти під res/fontтаким, як я, то ви можете змінити dir на наступне: -

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

0

Використовуйте https://github.com/delight-im/Android-AdvancedWebView бібліотеку.

в даних 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>

у xml:

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

в Java:

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

-3

Ось як ви завантажуєте htmlData у веб-перегляд:

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

де getHtmlData(activity,**htmlData**)повертає рядок html-коду.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.