WebView如何加載本地字體
看過(guò)網(wǎng)上好多的文章千篇一律绊诲,都是這種答案硫豆,用 “file:///android_assets/averta.ttf”.
而這種方式本人試下來(lái)穗椅,都只適用于字體文件存放在當(dāng)前 [主module] 的assets文件夾下吁恍,而最終還是找到了官方的解決方案胰舆,能支持字體文件存在于作為主題色的 [子module] 里assets里的情況册舞。完美蕴掏。
權(quán)威還是得官方。寶藏全路徑如下:
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.message.utils;
import android.content.Context;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.util.Log;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.core.content.res.ResourcesCompat;
import androidx.core.graphics.drawable.DrawableCompat;
import java.util.Locale;
public class ResourcesUtils {
/**
* @param fontsFileName| exmaple:|
* "font/{family}_{weight}.ttf"
* "font/{family}-{weight}.ttf"
* "font/{Family}_{Weight}.ttf"
* "font/{Family}-{Weight}.ttf"
* @return Typeface || null
*/
@Nullable
public static Typeface getFontTypeface(Context context, String fontsFileName) {
Typeface localTypeface = null;
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\"");
}
try {
if (context != null) {
int resId = context.getResources().getIdentifier(splitFontsFileName2[1], splitFontsFileName2[0], context.getPackageName());
ConversationLog.INSTANCE.i("ChatThemeFont: font resId=" + resId + "|" + splitFontsFileName[0] + "|" + splitFontsFileName2[0] + "|" + context.getPackageName());
if (resId > 0) {
localTypeface = ResourcesCompat.getFont(context, resId);
} else {
localTypeface = Typeface.createFromAsset(context.getAssets(), lowerCaseFontsFileName);
}
} else {
ConversationLog.INSTANCE.e("ChatThemeFont: context cannot be null.please check.");
}
} catch (Exception e) {
ConversationLog.INSTANCE.e("ChatThemeFont: mapping fonts error,fonts file not found==>" + fontsFileName + "|" + e.getMessage());
}
return localTypeface;
}
public static int getDrawableId(Context context, String drawableName) {
if (context != null) {
return context.getResources().getIdentifier(drawableName, "drawable", context.getPackageName());
} else {
ConversationLog.INSTANCE.e("ChatThemeDrawable: context cannot be null.please check.");
}
return 0;
}
@Nullable
public static Drawable getDrawable(Context context, String drawableName) {
int resourceId = getDrawableId(context, drawableName);
if (resourceId != 0) {
return ContextCompat.getDrawable(context, resourceId);
}
return null;
}
@Nullable
public static Drawable getTargetTintDrawable(Drawable drawable, int color) {
if (drawable != null) {
Drawable newDrawable = DrawableCompat.wrap(drawable);
DrawableCompat.setTint(newDrawable, color);
return newDrawable;
}
return null;
}
}
應(yīng)該還有種方式可以通過(guò)自動(dòng)生成R.font.id文件加載调鲸,但目前沒(méi)試過(guò).
-----------------------------End-----------------------------