该库具有以下特点:

支持 emoji 表情图片

支持 gif 动态表情输入显示

支持单张贴图表情(与微信收藏表情一致)

支持题图表情库的添加删除

效果图:

快速使用

引入库

compile 'com.pandaq:PandaEmoView:1.0.0'

表情资源及配置文件

默认的 emoji 和 gif 表情以及他们的配置文件是放在开发包 assets 目录下的,若表情比较多比较大也可自行修改源码在 APP 启动时从服务器下载。

emoji 表情配置文件

非自定义 sticker 配置文件(自定义 sticker 是没有配置文件的)

具体使用规则

与表情输入控件相关的 EditText 必须使用 PandaEditText

PandaEditText 只是重写了 onKeyPreIme() 获取按返回键的通知,继承自 EditText 的控件可继承 PandaEditText 自定义

1.应用 Application 中进行全局参数配置

private void configPandaEmoView() {

new PandaEmoManager.Builder()

.with(getApplicationContext()) // 传递 Context

.configFileName("emoji.xml")// 配置文件名称

.emoticonDir("face") // asset 下存放表情的目录路径(asset——> configFileName 之间的路径,结尾不带斜杠)

.sourceDir("images") // 存放 emoji 表情资源文件夹路径(emoticonDir 图片资源之间的路径,结尾不带斜杠)

.showAddTab(true)//tab栏是否显示添加按钮

.showStickers(true)//tab栏是否显示贴图切换按键

.showSetTab(true)//tab栏是否显示设置按钮

.defaultBounds(30)//emoji 表情显示出来的宽高

.cacheSize(1024)//加载资源到内存时 LruCache 缓存大小

.defaultTabIcon(R.drawable.ic_default)//emoji表情Tab栏图标

.emojiColumn(7)//单页显示表情的列数

.emojiRow(3)//单页显示表情的行数

.stickerRow(2)//单页显示贴图表情的行数

.stickerColumn(4)//单页显示贴图表情的列数

.maxCustomStickers(30)//允许添加的收藏表情数

.imageLoader(new IImageLoader() {

@Override

public void displayImage(String path, ImageView imageView) { // 加载贴图表情的图片加载接口

Picasso.with(getApplicationContext())

.load(path)

.fit()

.centerCrop()

.into(imageView);

}

})

.build(); //构建 PandaEmoManager 单利

}

2.使用此控件的 Activity 在 manifest 文件中配置

// 这句是一定要加上的。

android:windowSoftInputMode="adjustResize"

3.使用此控件的界面 xml 文件规则

布局规则如下图,lockView 即是我们正常显示内容的 View 它与表情输入控件 PandaEmoView 属于同一层级,父布局必须为纵向线性布局,且设置 lockView 权重为 1 ,PandaEmoView 高度包裹内容即可

4.使用控件的 Activity Java 代码设置

//界面控件初始化后 .attachEditText()绑定输入控件

//初始化 KeyBoardManager,PandaEmoView.attachEditText() 必须在后调用

主要使用类及公有方法概览

PandaEmoEditText

表情输入框继承自 EditText 只对 onKeyIme() 进行复写用于监听输入键盘或者软键盘的弹出与关闭

PandaEmoView

表情输入控件 View 继承自 RelativeLayout

方法

返回值

参数

描述

attachEditText(PandaEmoEditText input)

void

表情输入控件(如使用自定义 EditText 可直接继承重写)

绑定输入控件

getAttachEditText()

void

获取当前表情控件绑定的输入框控件

reloadEmos

void

position 重载表情控件数据后默认选中 Tab 的 position

添加或者删除表情数据后重载刷新表情控件

PandaEmoManager

PandaEmoManager 为核心配置类,表情控件的各种参数都通过此类的构造器进行配置

属性

类型

描述

默认值

EMOT_DIR

String

默认表情图在 assets 中的路径 (assets 目录到配置 xml 文件之间的部分的路径,demo 中的 face)

face

SOURCE_DIR

String

EMOT_DIR 目录下存放图片资源的文件夹路径 (demo 中的 images)

source_default

STICKER_PATH

String

Sticker贴图包的存放目录,该目录下的每一个文件目录都为一个贴图包

/data/data/< package name>/files/sticker

CACHE_MAX_SIZE

int

加载表情 LruCache 缓存大小

1024

DEFAULT_EMO_BOUNDS_DP

int

表情图显示大小(非贴图表情)

30dp

defaultIcon

int

表情 Tab 资源文件名

R.drawable.ic_default

mContext

Context

上下文

null

mConfigFile

String

EMOT_DIR 目录下的 emoji 配置文件名称

emoji_default.xml

mIImageLoader

IImageLoader

Sticker 图片加载器接口,加载方式外部传入

null

MAX_CUSTOM_STICKER

int

最大添加的自定义贴图表情数

30

EMOJI_ROW

int

emoji 表情单页行数

3

EMOJI_COLUMN

int

emoji 表情单页列数

7

STICKER_ROW

int

sticker 表情单页行数

2

STICKER_COLUMN

int

sticker 表情单页列数

4

showAddButton

boolean

tab 栏是否显示添加按钮

ture

showSetButton

boolean

tab 栏是否显示设置按钮

ture

showStickers

boolean

tab 栏是否显示贴图按钮(所以 sticker)

ture

方法

返回值

参数

描述

init()

void

无参

初始化 拼接 Sticker 路径及创建自定义贴图 文件夹 (STICKER_PATH + "/selfSticker" )

makePattern()

Pattern

无参

创建 emoji 正则匹配器

剩余方法都为属性值的 getter() setter() 不在赘述。

PandaEmoManager.Builder

PandaEmoManager 的构造器类,属性及方法都与 PandaEmoManager 一一对应;

KeyBoardManager

KeyBoardManager 为输入法软键盘与表情输入控件协调管理类

属性

类型

描述

默认值

SHARE_PREFERENCE_NAME

String

用于存储键盘高度的 SP 的名字

"EmotionKeyBoard"

SHARE_PREFERENCE_SOFT_INPUT_HEIGHT

String

用于存储键盘高度的 key

"EmotionKeyBoard"

mActivity

Activity

控件依附的 Activity 界面

null

mEmotionView

PandaEmoView

当前管理的表情输入控件

null

interceptBackPress

boolean

是否拦截返回键

false

lockView

View

锁定高度的 View(即同一线性父布局中,表情控件之外的布局视图)

null

mOnEmotionButtonOnClickListener

OnEmotionButtonOnClickListener

表情显示控制按钮监听

null

mOnInputShowListener

OnInputShowListener

监听输入栏的弹出与关闭

null

方法

返回值

参数

描述

with()

KeyBoardManager

Activity : 当前输入控件依附的 Activity

初始化 KeyBoardManager 创建单例

bindToLockContent()

KeyBoardManager

lockView:切换需要锁定高度的 View

赋值给内部属性 lockView

bindToEmotionButton()

KeyBoardManager

View...: 多个 View 参数,切换控制按钮

为输入控件绑定控制按钮

setEmotionView()

KeyBoardManager

PandaEmoView: 被管理的表情控件

绑定当前管理的输入控件(绑定的控件必须在此之前调用 PandaEmoView.attachEditText() 否则内部将会空指针)

interceptBackPress()

boolean

null

在 Activity 的 backPressd() 中检查是否需要拦截返回键关闭输入栏而不是退出界面

hideInputLayout()

void

null

供外部调用关闭输入栏(不能未初始化直接调用)

showInputLayout()

void

null

供外部调用显示输入栏(不能未初始化直接调用)

EmoticonManager

EmoticonManager 为 emoji 表情加载管理类,此类提供方法将资源文件根据配置文件加载进内存,方法大多数为私有方法,源码中可查看注释。

StickerManager

StickerManager 为 sticker 表情加载管理类,此类提供方法将资源文件根据配置文件加载进内存,与 EmoticonManager 类似

PandaEmoTranslator

PandaEmoTranslator 为 emoji 表情 [文字] 转表情的转换工具类

方法

返回值

参数

描述

getInstance()

PandaEmoTranslator

null

获取文本表情转换器单例

setMaxGifPerView()

void

maxGifPerView: 每个 TextView 控件最多显示动态表情的个数

设置每个 TextView 控件最多显示动态表情的个数,超过此数全部显示为静态表情

getMaxGifPerView()

int

null

获取每个 TextView 控件最多显示动态表情的个数

makeGifSpannable()

SpannableString

classTag:PandaEmoView 依附的 ActivityTag(推荐使用 Activity.getLocalClassName());value : 待替换的文本 ;gif 运行回调(回调中需要刷新 TextView 重绘)

整段图文混排,支持 gif 和静态 emoji

makeEmojiSpannable()

SpannableString

classTag:PandaEmoView 依附的 ActivityTag(推荐使用 Activity.getLocalClassName());value : 待替换的文本 ;gif 运行回调(回调中需要刷新 TextView 重绘)

整段图文混排,所以内容转换为静态 emoji

resumeGif()

void

activityTag : makeGifSpannable() 传入的 tag 名

开始 activityTag 对应的所有 gif 表情执行

pauseGif()

void

暂停所有的 Gif 表情运行

clearGif()

void

activityTag : makeGifSpannable() 传入的 tag 名

停止 activityTag 对应的所有 gif 表情执行,并将期从任务栈中移除

关于内存优化

因为表情,gif 表情,自定义贴图,表情包贴图这些都涉及到图片资源加载到内存中。因此开发过程中不可避免的也遇到了许多的内存优化相关的问题。

工具

就地取材,直接使用 Android Studio 的 Monitors 工具可以直观的查看到应用运行过程中内存的变化过程

优化点1 —— Gif 播放类的优化

问题:

参考网上的 gif 图文混排项目,虽然实现了 gif 与文字的图文混排效果,但存在致命的缺陷。该项目中每一个 gif 动态表情图都有一个对应的 Runable 对象去执行 gif 图片的逐帧播放,当一个表情重复输入也会有新的 Runable 对象去执行这样的操作,这样做的后果就是当输入的表情数量增加时,所消耗的内存是持续增长的。这显然不能满足生产使用的需求。

解决方案:

考虑到此处内存增加的原因是让表情动起来的 Runable 泛滥引起的,因此减少 Runable 的数量就是解决此处内存问题的关键。我的方案做的比较彻底,整个应用 gif 表情这一块儿都交给一个 Runable 去处理,这个 Runable 在 PandaTranslator 中进行图文转化时会被初始化

// PandaTranslator 的 103 - 107 行

103 if (mGifRunnable == null) {

104 mGifRunnable = new GifRunnable(gifDrawable, mHandler);

105 } else {

106 mGifRunnable.addGifDrawable(gifDrawable);

107 }

因为 PandaTranslator 是一个单例实现,所以在他初始化后 mGifRunnable 也将保持唯一性。无论是新建初始化还是 addGifDrawable() 都是把 Gif 表情对象放入 GifRunnable 中的一个 Map 中。Map 的 key value 分别是表情控件依附的 Activity 的 LocalName 和 一个 AnimatedGifDrawable 的 List。在 GifRunnable 的 run 方法中会根据当前的 Activity 的 LocalName 去取出对应的 AnimatedGifDrawable 列表,遍历执行并按第一张 gif 表情的帧间隔去刷新 Drawable 并触发 TextView 刷新回调

@Override

public void run() {

isRunning = true;

if (currentActivity != null) {

List runningDrawables = mGifDrawableMap.get(currentActivity);

if (runningDrawables != null) {

for (AnimatedGifDrawable gifDrawable : runningDrawables) {

AnimatedGifDrawable.RunGifCallBack listener = gifDrawable.getUpdateListener();

List runningListener = listenersMap.get(currentActivity);

if (runningListener != null) {

// 避免一个 TextView 多个表情时重复添加回调

if (!runningListener.contains(listener)) {

runningListener.add(listener);

}

} else {

// 为空时肯定不存在直接添加

runningListener = new ArrayList<>();

runningListener.add(listener);

listenersMap.put(currentActivity, runningListener);

}

gifDrawable.nextFrame();

}

for (AnimatedGifDrawable.RunGifCallBack callBack : listenersMap.get(currentActivity)) {

if (callBack != null) {

callBack.run();

}

}

frameDuration = runningDrawables.get(0).getFrameDuration();

}

}

mHandler.postDelayed(this, frameDuration);

}

这样就实现了全局使用一个 Runable 来执行 gif 动起来的任务,不同的界面也仅需要将该界面的 AnimatedGifDrawable 对象加入任务 Map 即可。

优化点2 —— 界面暂停或退出时 Gif 播放资源同步退出回收

上面说到的将 AnimatedGifDrawable 列表加入任务 Map,只进不出显然是不科学的也会持续增加内存的消耗。我们希望在 Activity 退出时能将将当前 Activity 的 AnimatedGifDrawable 列表销毁移除,在界面不可见但是可能会恢复时(pause 状态)暂停 Runable 的执行,减少资源消耗。于是 GifRunable 提供了如下三个方法给外部调用

/**

* 使用了表情转换的界面退出时调用,停止动态图handler

*/

public void clearHandler(String activityName) {

currentActivity = null;

//清除当前页的数据

mGifDrawableMap.remove(activityName);

// 当退出当前Activity后没表情显示时停止 Runable 清除所有动态表情数据

listenersMap.remove(activityName);

if (mGifDrawableMap.size() == 0) {

clearAll();

}

}

private void clearAll() {

mHandler.removeCallbacks(this);

mHandler.removeCallbacksAndMessages(null);

mGifDrawableMap.clear();

isRunning = false;

}

/**

* 启动运行

*/

public void startHandler(String activityName) {

currentActivity = activityName;

if (mGifDrawableMap != null && mGifDrawableMap.size() > 0 && !isRunning) {

run();

}

}

它的调用入口都在 PandaTranslator 中,然后我们只需在使用到 PandaEmoView 或者直接在 BaseActivity 的 onResume(),onPause(),onDestory() 中分别调用以下三个方法:

PandaTranslator.getInstance().resumeGif(activityLocalName);

PandaTranslator.getInstance().pauseGif();

PandaTranslator.getInstance().clearGif(activityLocalName)

优化点3 —— 使用 LruCache 缓存 emoji 资源

根据 LRU 规则将表情 Gif 缓存,避免重复加载创建新对象。

本库地址 PandaEmoView 欢迎 star 和提 issue

License

Copyright 2017 PandaQ.

Licensed under the Apache License, Version 2.0 (the "License");

you may not use this file except in compliance with the License.

You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software

distributed under the License is distributed on an "AS IS" BASIS,

WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

See the License for the specific language governing permissions and

limitations under the License.

mysql emoy表情_GitHub - PandaQAQ/PandaEmoView: emoji gif 表情图文混排,仿微信表情输入...相关推荐

  1. 类似微信表情图文混排(本地自定义表情)

    注:仅仅是提供思路 有些问题如隐藏系统自带的selectall按钮 自定义copy按钮 需要再解决 //首先引用 https://github.com/zekunyan/UITextViewDIYEm ...

  2. Unity Emoji表情(图文混排)2022最详细教程

    文章目录 前言 一.emoji是什么? emoji (日本在无线通信中所使用的视觉情感符号) 二.使用步骤 1.将源码文件导入自己的项目中 步骤一:将Editor目录文件EmojiAtlasBaker ...

  3. 仿微信表情输入键盘(支持 Gif 表情图文混排 )

    作者 | PandaQ404 地址 | http://www.jianshu.com/p/fddca2b0a26b 声明 | 本文是 PandaQ404 原创,已获授权发布,未经原作者允许请勿转载 简 ...

  4. 【游戏开发实战】Unity UGUI Text图文混排(聊天文字混表情),支持动态表情,出招吧表情帝

    文章目录 一.前言 二.最终效果 三.具体使用 1.导入表情素材 2.设置图片格式 3.生成表情图集 4.UI-EmojiFont.shader 5.材质球 四.测试 五.结束语 一.前言 点关注不迷 ...

  5. Swift3.0 功能二 (表情键盘与图文混排)

    随着iOS越来越多表情键盘以及图文混排的需求,本文运用Swift3.0系统的实现其功能以及封装调用方法,写的不好,如有错误望各位提出宝贵意见,多谢 项目源码地址: 相关知识点都有标识 项目源码地址 废 ...

  6. java使用微信表情代码_iOS高仿微信表情输入功能代码分享

    最近项目需求,要实现一个类似微信的的表情输入,于是把微信的表情扒拉出来,实现了一把.可以从这里下载源码.看起来表情输入没有多少东西,不外乎就是用NSTextAttachment来实现图文混排,结果在实 ...

  7. 转载 仿微信表情与软键盘冲突

    android高仿微信表情输入与键盘输入(详细实现分析) 本文是我在做仿微信IM时,解决表情栏与软键盘冲突时参考的文章,很有价值,故在此将之转载,以便后期学习. 目录(?)[+] 解决表情与键盘切换跳 ...

  8. Unity UGUI图文混排源码(三) -- 动态表情

    这里是根据图文混排源码(二)进一步修改的,其他链接也不贴了,就贴一个链接就好了,第一次看这文章的同学可以先去看看其他几篇文章 Unity UGUI图文混排源码(二):http://blog.csdn. ...

  9. 【小松教你手游开发】【系统模块开发】图文混排 (在label中插入表情)

    本身ngui是自带图文混排的,这个可以在ngui的Example里找到.但是为什么不能用网上已经说得很清楚,比如雨松momo的http://www.xuanyusong.com/archives/29 ...

最新文章

  1. 编写纳新网站后端的相关知识总结
  2. LeetCode 59 _ Sprial Matrix II 旋转矩阵2
  3. 剑指offer六十一之序列化二叉树(待补充)
  4. 浅谈JavaScript 函数作用域当中的“提升”现象
  5. swiper移入暂停_react中swiper注意事项及鼠标划入停止轮播
  6. 法在计算机课程中的应用,尝试教学法在中职《计算机应用基础》课程中的应用(原稿)...
  7. springboot前台页面写Java代码,接收后台数据,SpringBoot整合Thymeleaf的使用
  8. Moto XT1085 国行 解锁BL
  9. 计算机的软键盘在哪里,Win8软键盘在哪 Win8.1屏幕键盘打开方法图解
  10. php 博饼 源代码,php实现中秋博饼小游戏
  11. 程序员懒人投资大法之定投指数基金
  12. Ecstore的微信账号绑定会员免登录
  13. android 发广播屏蔽home键,如何在Android App中屏蔽(拦截)Home按键及其他按键
  14. RPLIDAR思岚雷达学习记录--4--雷达数据实时保存
  15. 数据库的ACID四原则
  16. 初次使用虹软人脸识别SDK C++版本
  17. 多边形面积的最长平分线的依托答辩记录
  18. 科普--固态硬盘那么多怎么选?
  19. N个节点的二叉树的形态数详细推导
  20. [渝粤教育] 南京邮电大学 现代邮政英语(English for Modern Postal Service) 参考 资料

热门文章

  1. vue 打包之后不兼容ie_vue项目打包后在IE浏览器报错,页面显示空白
  2. SCAP标准协议和威胁情报关键词术语
  3. Python三步爬取VMgirls小姐姐图片
  4. 软件测试显卡最高清晰度,FF14各种显卡测试,GTX 750以上就能开启最高画质
  5. 大华摄像头使用外网进行访问管理
  6. Playwright + Python爬虫
  7. html文字破碎特效,AE怎么制作破碎文字特效? ae文字破碎效果的制作方法
  8. 用人篇-曾国藩家书整理
  9. 地球系统模式(CESM)
  10. h5 实现扫码二维码及条形码(js多种实现方式)