จะเปลี่ยนแบบอักษรของ Webview ใน Android ได้อย่างไร


97

ฉันต้องการเปลี่ยนฟอนต์เริ่มต้นของ webview เป็นฟอนต์ที่กำหนดเอง ฉันใช้ Webview ในการพัฒนาแอปเบราว์เซอร์สองภาษาสำหรับ Android

ฉันพยายามหาอินสแตนซ์ของแบบอักษรที่กำหนดเองโดยวางแบบอักษรที่กำหนดเองในเนื้อหา แต่ยังไม่สามารถตั้งค่าแบบอักษรเริ่มต้นของ webview เป็นแบบอักษรของฉันได้

นี่คือสิ่งที่ฉันลอง:

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

ใครสามารถแก้ไขสิ่งนี้หรือแนะนำวิธีอื่นในการเปลี่ยนแบบอักษรเริ่มต้นของ webview เป็นแบบอักษรที่กำหนดเองได้หรือไม่?

ขอบคุณ!


ในที่สุดฉันก็รู้ว่าสิ่งนี้ไม่สามารถทำได้
Dhanika


ไม่ u Hi หาทางแก้ปัญหาใด ๆ สำหรับสิ่งที่ใบหน้านี้ตัวอักษรฉันกำลังพยายามภาษาฮินดีอักษรstackoverflow.com/q/5868198/501859 ช่วยฉันด้วยถ้าคุณมีวิธีแก้ปัญหา
Kishore

@Dhanika วิธีแก้ปัญหาที่ประสบปัญหาเดียวกัน
NagarjunaReddy

โปรดดูลิงก์นี้สำหรับการตั้งค่าแบบอักษรที่กำหนดเองในข้อความ Webview .. stackoverflow.com/a/25692052/3921740[1] [1]: stackoverflow.com/a/25692052/3921740
user3921740

คำตอบ:


112

มีตัวอย่างการทำงานของสิ่งนี้ในโครงการนี้ มันเดือดถึง:

  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 จากโค้ด:

    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 ("file: /// android_asset /", ... ทำงานได้ดีจากนั้นการอ้างอิงไฟล์แบบอักษรเป็น "/fonts/MyFont.otf" ควรใช้งานได้
JaakL

ในกรณีของฉันข้อมูลจะส่งคืนในรูปแบบของแท็กจาก ck editor (backend 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 และให้ไฟล์แบบอักษรในเนื้อหาของแอปพลิเคชัน
Paul Lammertsma

2
แบบอักษรของฉันอยู่ในres/fontโฟลเดอร์ เส้นทางจะเป็นอย่างไร? ฉันพยายามfile:///android_res/font/แล้วแต่ดูเหมือนจะไม่ได้ผล
Wirling

106

ฉันใช้รหัสนี้ :

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 เอง
Pascal Lindelauf

2
นี่คือวิธีแก้ปัญหาแบบโยกยกนิ้วให้
Saad Bilal

loadDataWithBaseURL ไม่ทำงานบน Android 4.1 และ 4.2 เวอร์ชัน :(
Misha Akopov

ไม่ทำงานสำหรับฉันใน 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 มันก็ใช้ได้ อย่างไรก็ตามใน WebView ของแอปของฉันในขณะที่ CSS แสดงข้อความจะปรากฏในแบบอักษรเริ่มต้นของ Android แม้ว่าจะเพิ่ม.ttfไปยังassets/fontsโฟลเดอร์ของโครงการแล้วก็ตาม ฉันกำลังทดสอบ 2.3.5 แต่สร้างเทียบกับ 2.1 นั่นอาจเป็นปัญหาหรือมีบางอย่างที่ฉันขาดหายไป?
Paul Lammertsma

1
ฉันพบความละเอียด: หากคุณสร้างไฟล์ HTML และวางไว้ในเนื้อหาการโหลดผ่านview.loadUrl()งานในขณะที่view.loadData()ไม่มี ฉันไม่รู้ว่าทำไมหลังไม่
Paul Lammertsma

4
ช้าไปหน่อย แต่ใช้งานได้กับ view.loadDataWithBaseUrl (null, content, mime, enconding, null)
เรา

29

สามารถทำได้ใน Android ฉันใช้เวลาสามวันในการแก้ปัญหานี้ แต่ตอนนี้ดูเหมือนง่ายมาก ทำตามขั้นตอนเหล่านี้เพื่อตั้งค่าแบบอักษรที่กำหนดเองสำหรับ Webview

1. เพิ่มแบบอักษรของคุณไปยังโฟลเดอร์ assets
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. ใช้รหัสด้านล่างเพื่อกำหนดมูลค่าสำหรับ Webview ของคุณ ที่นี่ฉันใช้ 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 ยังไม่โหลดแบบอักษรของฉัน มีอะไรพิเศษที่คุณทำหรือไม่? ขอบคุณ!
Zarah

วิธีการทำที่สำหรับ HTML stackoverflow.com/q/5868198/501859 ช่วยฉันด้วยถ้าคุณมีวิธีแก้ปัญหา
Kishore

มันได้ผลสำหรับฉันขอบคุณ Binary
Ravi Shanker Yadav

ฉันมีแบบอักษรในโฟลเดอร์สินทรัพย์และเปลี่ยน css ด้วยพา ธ ที่สมบูรณ์ของแบบอักษรและชื่อตระกูลแบบอักษรในเนื้อหาและหลังจากแก้ไขแล้วฉันกำลังโหลดเนื้อหาอีกครั้ง แต่ไม่สามารถเห็นเอฟเฟกต์การเปลี่ยนแบบอักษรได้ทันที
ราวี

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 ในเครื่องเพื่อตั้งค่าแบบอักษร webview สำหรับ 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 แบบนี้

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

เสร็จแล้ว คุณจะโหลดแบบอักษรจากแหล่งภายนอกได้ด้วยวิธีนี้

ตอนนี้เกี่ยวกับแบบอักษรของแอปแล้วการใช้แบบอักษร 1 แบบสำหรับ webview และแบบอักษรที่แตกต่างกันสำหรับทั้งแอปนั้นไม่สมเหตุสมผล คุณจึงสามารถใช้แบบอักษรที่ดาวน์โหลดได้ในแอปของคุณซึ่งใช้แหล่งข้อมูลภายนอกเพื่อโหลดแบบอักษรในแอป


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 library

ในข้อมูล 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:

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

โดยที่getHtmlData(activity,**htmlData**)ส่งคืนสตริงของโค้ด html

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.