怎样才能有b站表情包(高仿B站自定义表情)

首页教程更新时间:2023-05-15 03:41:53

在之前的文章给你的 Android App 添加自定义表情

中我们介绍了自定义表情的原理,没看过的建议看一下。这一篇文章将介绍它的应用,这里以B站的自定义表情面板为例,效果如下:

怎样才能有b站表情包,高仿B站自定义表情(1)

自定义表情的大小

给你的 Android App 添加自定义表情

的文章中,我们说过当我们写死表情的大小时,文字的 `textSize` 变大变小时都会有一点问题。

文字大于图片大小时,在多行的情况下,只有表情的行间距明显小于其他行的间距。如图:

怎样才能有b站表情包,高仿B站自定义表情(2)

为什么会出现这种情况呢?如下图所示,我在`top`, `ascent`, `baseline`, `descent`, `bottom`的位置标注了辅助线。

怎样才能有b站表情包,高仿B站自定义表情(3)

可以很清晰的看到,在只有表情的情况下,`top`, `ascent`, `descent`, `bottom`的位置有明显的问题。原因是 `DynamicDrawableSpan` 的 `getSize` 方法里面对 `FontMetricsInt` 进行了修改。解决的方式很简单,就是注释掉修改代码就行,代码如下。修改后,效果如下图所示。

@Override public int getSize(@NonNull Paint paint, CharSequence text, int start, int end, @Nullable FontMetricsInt fm) { Drawable d = getDrawable(); Rect rect = d.getBounds(); // // if (fm != null) { // fm.ascent = -rect.bottom; // fm.descent = 0; // // fm.top = fm.ascent; // fm.bottom = 0; // } return rect.right; }

怎样才能有b站表情包,高仿B站自定义表情(4)

不知道你还记不记得,我们说过`getSize` 的返回值是表情的**宽度**。上面的注释代码其实是设置了表情的高度,如果文本的大小少于表情时,就会显示不全,如下图所示:

怎样才能有b站表情包,高仿B站自定义表情(5)

那这种情况下,应该怎么办?这里不卖关子了,最终代码如下。解决方式非常简单就是分情况来判断。当文本的高度小于表情的高度时,设置 `fm` 的`top`, `ascent`, `descent`, `bottom`的值,让行的高度变大的同时让大的 emoji 图片居中。

@Override public int getSize(@NonNull Paint paint, CharSequence text, int start, int end, @Nullable FontMetricsInt fm) { Drawable d = getDrawable(); Rect rect = d.getBounds(); float drawableHeight = rect.height(); Paint.FontMetrics paintFm = paint.getFontMetrics(); if (fm != null) { int textHeight = fm.bottom - fm.top; if(textHeight <= drawableHeight) {//当文本的高度小于表情的高度时 //解决文字的大小小于图片大小的情况 float textCenter = (paintFm.descent paintFm.ascent) / 2; fm.ascent = fm.top = (int) (textCenter - drawableHeight / 2); fm.descent = fm.bottom = (int) (textCenter drawableHeight / 2); } } return rect.right; }

当然,你可能发现了,B站的 emoji 表情好像不是居中的。如下图所示,B站对 emoji 表情的处理类似基于 baseline 对齐。

怎样才能有b站表情包,高仿B站自定义表情(6)

上面最难理解的居中已经介绍,对于其他方式比如 baseline 和 bottom 就简单了。完整代码如下:

@Override public int getSize(@NonNull Paint paint, CharSequence text, int start, int end, @Nullable FontMetricsInt fm) { Drawable d = getDrawable(); if(d == null) { return 48; } Rect rect = d.getBounds(); float drawableHeight = rect.height(); Paint.FontMetrics paintFm = paint.getFontMetrics(); if (fm != null) { if (mVerticalAlignment == ALIGN_BASELINE) { fm.ascent = fm.top = (int) (paintFm.bottom - drawableHeight); fm.bottom = (int) (paintFm.bottom); fm.descent = (int) paintFm.descent; } else if(mVerticalAlignment == ALIGN_BOTTOM) { fm.ascent = fm.top = (int) (paintFm.bottom - drawableHeight); fm.bottom = (int) (paintFm.bottom); fm.descent = (int) paintFm.descent; } else if (mVerticalAlignment == ALIGN_CENTER) { int textHeight = fm.bottom - fm.top; if(textHeight <= rect.height()) { float textCenter = (paintFm.descent paintFm.ascent) / 2; fm.ascent = fm.top = (int) (textCenter - drawableHeight / 2); fm.descent = fm.bottom = (int) (textCenter drawableHeight / 2); } } } return rect.right; } 动态表情

动态表情实际上就是 gif 图。我们可以使用 android-gif-drawable 来实现。在 build.gradle 中增加依赖:

dependencies { ... implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.25' }

然后在我们创建自定义 ImageSpan 的时候传入参数就可以了:

val size = 192 val gifFromResource = GifDrawable(getResources(), gifData.drawableResource) gifFromResource.stop() gifFromResource.setBounds(0,0, size, size) val content = mBinding.editContent.text as SpannableStringBuilder val stringBuilder = SpannablestringBuilder(gifData.text) stringBuilder.setSpan(BilibiliEmojiSpan(gifFromResource, ALIGN_BASELINE), 0, stringBuilder.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)

关于 android-gif-drawable 更具体用法可以看 Android加载Gif动画android-gif-drawable的使用

总结

核心部分的代码已经介绍了,完整代码还在整理,后面放出来。最后求一个免费的赞吧

,
图文教程
相关文章
热门专题
推荐软件
奇热小说
奇热小说
下载
QQ2019手机版
QQ2019手机版
下载
王者荣耀
王者荣耀
下载
百度浏览器迷你版
百度浏览器迷你版
下载
2345浏览器手机版
2345浏览器手机版
下载
网易邮箱
网易邮箱
下载
爱奇艺
爱奇艺
下载
网易云音乐
网易云音乐
下载
WPSOffice
WPSOffice
下载
优酷
优酷
下载
谷歌浏览器(Chrome)
谷歌浏览器(Chrome)
下载
迅雷看看播放器
迅雷看看播放器
下载
UC浏览器
UC浏览器
下载
QQ音乐
QQ音乐
下载
阿里旺旺买家版v9.12.10C官方版
阿里旺旺买家版v9.12.10C官方版
下载
360安全卫士v12.1官方版
360安全卫士v12.1官方版
下载
猜你喜欢
云睿社区v1.000.1000000.6.R官方版
云睿社区v1.000.1000000.6.R官方版
下载
兔八啦影视网手机版
兔八啦影视网手机版
下载
女士发型
女士发型
下载
飞马钱包app
飞马钱包app
下载
枪王吃鸡大战计划
枪王吃鸡大战计划
下载
住哪儿app
住哪儿app
下载
刀塔帝国电脑版
刀塔帝国电脑版
下载
WiFi上网加速仪
WiFi上网加速仪
下载
分手模拟器
分手模拟器
下载
康展运动
康展运动
下载
VirtualPC2007绿色精简中文版
VirtualPC2007绿色精简中文版
下载
亲亲小保社保管家电脑版
亲亲小保社保管家电脑版
下载
无双猛将电脑版
无双猛将电脑版
下载
大吉陌生人TV版v2.0
大吉陌生人TV版v2.0
下载
潜江千分九游版
潜江千分九游版
下载
代号艾塔
代号艾塔
下载