You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在assets目录CSS中引用res/fonts字体及配置WebView使用该字体?

嘿,这两个问题都是Android WebView里自定义字体的常见场景,我来给你梳理下实操性强的解法:

问题1:如何在assets文件夹中的CSS文件里引用res/fonts目录下的字体文件?

直接在CSS里写res/fonts的路径是行不通的——WebView对assets和res资源的访问规则完全不一样。这里有两种省心的方案:

  • 方案1:复制字体到assets目录(最推荐)
    把res/fonts里的目标字体(比如my_custom_font.ttf)复制到assets下的子文件夹,比如assets/fonts/。然后在assets的CSS里用相对路径直接引用:

    @font-face {
        font-family: 'MyCustomFont';
        src: url('./fonts/my_custom_font.ttf') format('truetype');
        font-weight: normal;
        font-style: normal;
    }
    

    这种方法零额外配置,WebView能直接解析assets内的相对路径,踩坑概率最低。

  • 方案2:通过Content URI引用res字体
    如果不想复制字体文件,可以通过代码生成res字体的可访问URI,再注入到CSS中:

    1. 在Kotlin/Java代码里生成字体的Content URI:
      val fontUri = "android.resource://${packageName}/R.font.my_custom_font"
      
    2. 把这个URI直接写进HTML的style标签(或者通过JS注入),比如:
      @font-face {
          font-family: 'MyCustomFont';
          src: url('android.resource://com.your.app.package/R.font.my_custom_font') format('truetype');
      }
      

    注意:Android 10+可能需要确保WebView有权限访问这个URI,不过默认情况下是允许的。

问题2:配置WebView使用res/font目录内的自定义字体,如何调整assets文件夹中的CSS?

核心思路是让assets里的CSS能拿到res字体的有效访问路径,这里有两种实现方式:

  • 方式1:在HTML中嵌入动态生成的Font Face规则
    你可以在代码里生成包含res字体URI的@font-face规则,插入到HTML的中,再引用assets的CSS:

    1. 代码生成字体样式:
      String packageName = getPackageName();
      String fontUri = "android.resource://" + packageName + "/R.font.my_custom_font";
      String fontFaceStyle = "<style>@font-face { font-family: 'MyCustomFont'; src: url('" + fontUri + "') format('truetype'); }</style>";
      
    2. 加载HTML时,把这个样式标签和assets的CSS一起引入:
      <html>
          <head>
              <!-- 动态插入的字体规则 -->
              <style>@font-face { font-family: 'MyCustomFont'; src: url('android.resource://com.your.app.package/R.font.my_custom_font') format('truetype'); }</style>
              <!-- 引用assets里的CSS -->
              <link rel="stylesheet" href="file:///android_asset/styles.css">
          </head>
          <body>
              <p class="custom-text">使用自定义字体的文本</p>
          </body>
      </html>
      

    之后assets的CSS就可以直接用font-family: 'MyCustomFont';来调用这个字体了,比如:

    .custom-text {
        font-family: 'MyCustomFont';
        font-size: 16px;
    }
    
  • 方式2:通过JS注入替换CSS中的字体路径
    如果不想修改HTML结构,可以在WebView加载完成后,用JS把assets CSS里的占位路径替换成res字体的URI:

    1. 先开启WebView的JavaScript支持:
      webView.settings.javaScriptEnabled = true
      
    2. 在页面加载完成的回调中注入JS:
      webView.webViewClient = object : WebViewClient() {
          override fun onPageFinished(view: WebView?, url: String?) {
              super.onPageFinished(view, url)
              val fontUri = "android.resource://${packageName}/R.font.my_custom_font"
              view?.evaluateJavascript("""
                  // 遍历所有样式表,替换指定字体的路径
                  Array.from(document.styleSheets).forEach(sheet => {
                      try {
                          Array.from(sheet.cssRules).forEach(rule => {
                              if (rule.type === CSSRule.FONT_FACE_RULE && rule.style.fontFamily === "'MyCustomFont'") {
                                  rule.style.src = `url('$fontUri') format('truetype')`;
                              }
                          });
                      } catch(e) {} // 跨域样式表可能会报错,忽略即可
                  });
              """, null)
          }
      }
      
    3. 此时assets的CSS可以先写一个占位的@font-face:
      @font-face {
          font-family: 'MyCustomFont';
          src: url('placeholder.ttf') format('truetype'); /* 占位用的无效路径 */
      }
      

    页面加载完成后,JS会自动把占位路径替换成res字体的实际URI。


内容的提问来源于stack exchange,提问作者efor18

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:50:17