美文网首页
Android(java/kotlin) 加载本地字体

Android(java/kotlin) 加载本地字体

作者: 想看烟花么 | 来源:发表于2022-05-19 09:15 被阅读0次

    WebView如何加载本地字体

    看过网上好多的文章千篇一律,都是这种答案,用 “file:///android_assets/averta.ttf”.
    而这种方式本人试下来,都只适用于字体文件存放在当前 [主module] 的assets文件夹下,而最终还是找到了官方的解决方案,能支持字体文件存在于作为主题色的 [子module] 里assets里的情况。完美。
    权威还是得官方。宝藏全路径如下:
    https://stackoverflow.com/questions/3900658/how-to-change-font-face-of-webview-in-android
    https://developer.android.com/reference/androidx/webkit/WebViewAssetLoader

    webview.setWebClientForLoadingLocalFontFamily()
            
    val htmlContentResult = WebViewUtils.getHtmlWithFontSet("Averta","/res/font/averta_regular.ttf",yourHtmlText)
            
    webview.loadDataWithBaseURL(WebViewUtils.FLAG_FONT_SET, htmlContentResult,
                    "text/html", "utf-8", null)
    
    class WebViewUtils{
    companion object {
            const val FLAG_FONT_SET = "https://appassets.androidplatform.net"
    
            /**
             * @param filePath is file path but not absolutely path
             * example: the correct format like /res/font/averta_regular.ttf
             * @notice: using this function after [setWebClientForLoadingLocalFontFamily] called.
             */
            fun getHtmlWithFontSet(fontFamily: String, filePath: String, html: String): String {
                val fontStyle =
                    "<style type=\"text/css\">@font-face {font-family: $fontFamily;src: url(\"$FLAG_FONT_SET$filePath\")}body,* {font-family: $fontFamily;}</style>"
                return "$fontStyle$html"
            }
        }
    
        fun setWebClientForLoadingLocalFontFamily(isResourcePath: Boolean = true) {
            context?.let {
                val assetLoader = if (isResourcePath) {
                    WebViewAssetLoader.Builder()
                        .addPathHandler(
                            "/res/",
                            WebViewAssetLoader.ResourcesPathHandler(it))
                        .build()
                } else {
                    WebViewAssetLoader.Builder()
                        .addPathHandler(
                            "/assets/",
                            WebViewAssetLoader.AssetsPathHandler(it))
                        .build()
                }
    
                webViewClient = object : WebViewClient() {
                    override fun shouldInterceptRequest(
                        view: WebView,
                        request: WebResourceRequest,
                    ): WebResourceResponse? {
                        return assetLoader.shouldInterceptRequest(request.url)
                    }
                }
            }
        }
    }
    

    加载读取本地字体

    package com.patrik.chatsdk.theme.model;
    
    import android.graphics.Typeface;
    import android.util.Log;
    
    import androidx.core.content.res.ResourcesCompat;
    
    import com.patrik.chatsdk.theme.ChatTheme;
    
    import java.util.Locale;
    
    public class ChatThemeFont {
        public Typeface typeface = null;
        public Float size;
    
        /**
         * @param fontsFileName | exmaple:
         *                      "font/{family}_{weight}.ttf"
         * @param mySize        |Float
         */
        public ChatThemeFont(String fontsFileName, Float mySize) {
            try {
                if (fontsFileName == null) {
                    throw new NullPointerException("Fonts file cannot found");
                }
                if (!fontsFileName.endsWith(".ttf")) {
                    throw new IllegalStateException("Fonts file cannot found==>" + fontsFileName);
                }
                String lowerCaseFontsFileName = fontsFileName.toLowerCase(Locale.ROOT);
                String[] splitFontsFileName = lowerCaseFontsFileName.split("\\.");
                if (splitFontsFileName.length != 2) {
                    throw new IllegalStateException("Parameter of 'fontsFileName' format is invalid,error_1==>" + lowerCaseFontsFileName + "\nThe correct fonts file format is \"font/{family}_{weight}.ttf\"");
                }
                String[] splitFontsFileName2 = splitFontsFileName[0].split("/");
                if (splitFontsFileName2.length != 2) {
                    throw new IllegalStateException("Parameter of 'fontsFileName' format is invalid,error_2==>" + lowerCaseFontsFileName + "\nThe correct fonts file format is \"font/{family}_{weight}.ttf\"");
                }
                if (ChatTheme.application != null) {
                    int resId = ChatTheme.application.getResources().getIdentifier(splitFontsFileName2[1], splitFontsFileName2[0], ChatTheme.application.getPackageName());
                    Log.i("ChatThemeFont", "font resId=" + resId + "|" + splitFontsFileName[0] + "|" + splitFontsFileName2[0] + "|" + ChatTheme.application.getPackageName());
                    if (resId > 0) {
                        this.typeface = ResourcesCompat.getFont(ChatTheme.application, resId);
                    } else {
                        this.typeface = Typeface.createFromAsset(ChatTheme.application.getAssets(), lowerCaseFontsFileName);
                    }
                }
            } catch (Exception e) {
                String errorFileName = "";
                if (fontsFileName != null) {
                    errorFileName = fontsFileName;
                }
                Log.e("ChatThemeFont", "Mapping fonts error,fonts file not found==>" + errorFileName);
            }
            this.size = mySize;
        }
    }
    

    应该还有种方式可以通过自动生成R.font.id文件加载,但目前没试过.
    -----------------------------End-----------------------------

    我也是有底线的,感谢您的耐心阅读,欢迎支持与点赞。

    相关文章

      网友评论

          本文标题:Android(java/kotlin) 加载本地字体

          本文链接:https://www.haomeiwen.com/subject/wcmudrtx.html