方案一
获取
在iconFont上已项目形式打包下载图标。
具体使用可查看 https://www.iconfont.cn/help/detail?spm=a313x.7781069.1998910419.d8cf4382a&helptype=code
配置到项目
仅需将.ttf文件放到assets目录下即可。
使用
使用前对TextView初始化
要正常显示iconfonts,需要对TextView设置Typeface。可以考虑自定义一个IconFontView继承TextView
private void initMyTextView(View rootView) {
Typeface typeface = Typeface.createFromAsset(getActivity().getAssets(),"font/iconfont.ttf");
textView = rootView.findViewById(R.id.textview_first);
textView.setTypeface(typeface);
}
使用方法
1、xml文件中引用string.xml
string.xml
<resources>
<!--对应关系见demo.html-->
<string name="icontest"></string>
<!--unicode码,对应关系见 iconfont.json-->
<string name="icontest2">\ue7a8</string>
</resources>
fragment_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".FirstFragment">
<TextView
android:id="@+id/textview_first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/icontest"
android:textSize="20sp"
app:layout_constraintBottom_toTopOf="@id/button_first"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button_first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/icontest2"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textview_first" />
</androidx.constraintlayout.widget.ConstraintLayout>
2、java文件中引用string资源文件
textView.setText(R.string.icontest);//
textView.setText(R.string.icontest2);//\ue7a8
3、直接使用unicode编码
textView.setText("\ue794");
// textView.setText("");//无效
方案二
(参考文章: https://blog.csdn.net/zhangphil/article/details/79630170 )
配置到项目
仅需将.ttf文件放到res/font目录下即可
使用
TextView初始化
直接在布局文件中添加属性 fontFamily即可,相比方案一,省去动态设置facetype的代码。
<TextView
android:id="@+id/textview_first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/icontest"
android:textSize="20sp"
android:fontFamily="@font/iconfont"
app:layout_constraintBottom_toTopOf="@id/button_first"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
使用方法
同方案1
进阶方案
使用font_class字段显示icon
将.json文件也保存到assets文件夹下,通过读取该文件来获取json,并从json中找到与font_class对应的unicode。
代码如下:
/*根据fontClass字符串找出unicode编码,找不到返回""*/
private String getJsonFile(String fontClass) {
String unicode = "";
InputStream inputStream = null;
try {
//从assets中获取json文件,读取到byte[]中
AssetManager assetManager = getActivity().getAssets();
inputStream = assetManager.open("font/iconfont.json");
byte[] bytes = new byte[inputStream.available()];
inputStream.read(bytes);
//将byte[]数组转成json,并遍历json查找对应的unicode
String json = new String(bytes);
JSONObject iconJson = new JSONObject(json);//这里要注意异常处理
JSONArray iconArray = iconJson.getJSONArray("glyphs");
for (int i = 0; i < iconArray.length(); i++) {
JSONObject icon = (JSONObject) iconArray.get(i);
if (icon.getString("font_class").equals(fontClass)) {
unicode = icon.getString("unicode");
char c = (char) Integer.parseInt(unicode, 16);
unicode = c + "";
break;
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} finally {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
return unicode;
}
}
}
用TextView直接显示iconfont的不居中问题
使用TextView直接显示iconfont会导致该控件的实际宽高偏大,使得界面布局上要对齐很困难。如图:
可以看到,在我没有设置padding的情况下,TextView还是给字体图标做了一些操作,使得他顶部和右边都留有一定空间。(个人盲猜应该是涉及到行距和字距的配置)
询问了我搞ios开发的同事,他的方法是将iconfont转成bitmap,然后使用ImageView显示图标。亲测可行。
解决方案:将iconfont绘制成bitmap
/*将图标字体绘制成bitmap(解决直接使用textview显示图标不居中问题)
* @param bitmapWidth 要创建的图片尺寸
* @param iconfont 图标的unicode编码
* @param color 图标颜色*/
private Bitmap drawBitmap(int bitmapWidth, String iconfont, int color) {
//color 图标颜色
/*画布大小*/
Bitmap bitmap = Bitmap.createBitmap(bitmapWidth, bitmapWidth, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
paint.setColor(color);
paint.setTextSize(bitmapWidth * 1f);//字体大小
paint.setTextAlign(Paint.Align.CENTER);
//typeface
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//该方法仅支持android8.0
paint.setTypeface(getResources().getFont(R.font.iconfont));
} else {
//由于8.0以下无法使用getResources().getFont(R.font.iconfont)方法,因此assets中也需要一份ttf文件!先暂时放两份ttf文件,以后在想办法
Typeface typeface = Typeface.createFromAsset(mContext.getAssets(), "font/iconfont.ttf");
paint.setTypeface(typeface);
}
//利用 rect来获取 字体的中间点
Rect r = new Rect(0, 0, bitmapWidth, bitmapWidth);
paint.getTextBounds(iconfont, 0, iconfont.length(), r);
float y = bitmapWidth / 2f + r.height() / 2f - r.bottom;
canvas.drawText(iconfont, bitmapWidth / 2, y, paint);
return bitmap;
}