Android键盘自定义表情包,关于自定义表情键盘...
在做输入的时候,除了可以输入系统的表情符号,项目中通常还要求输入表情图片
表情图片
1、正则表达式
一个正则表达式,就是一串有特定意义的字符,首先要编译成为一个Pattern对象,然后使用matcher()方法来生成一个Matcher实例,接着便可以使用该 Matcher实例对目标字符串进行匹配工作。
Pattern类:
static Pattern compile(String regularExpression):将给定的正则表达式编译并赋予给Pattern类
Matcher matcher(CharSequence input) :生成一个match对象
Matcher类:
boolean find()
尝试在目标字符串里查找下一个匹配子串,如果没有,返回false
String group()
返回当前查找,所组匹配的子串
private SpannableString dealExpression(Context context) {
...
// 正则表达式比配字符串里是否含有表情,如: 我好[开心]啊
String zhengze = "\\[[^\\]]+\\]";
// 通过传入的正则表达式来生成一个pattern
Pattern pattern = Pattern.compile(zhengze, Pattern.CASE_INSENSITIVE);
//得到matcher
Matcher matcher = pattern.matcher(spannableString);
//尝试在目标字符串里查找下一个匹配子串,如果没有,返回false
while (matcher.find()) {
//得到匹配的子串
String key = matcher.group();
...
}
}
2、表情文字到表情图片的转变
如果将表情字符 212[开心]2[调皮] ,转变成表情图片,如下图,可以使用SpannableString。
建立图片名称---资源ID的键值对,得到了名称,就得到了资源ID
通过正则表达式,得到匹配某种规则的字符(图片名称)
根据得到的资源文件ID,生成bitmap,通过Span进行包装
使用SpannableString,把某个区间的字符,替换成资源图片
构造函数如下:
public ImageSpan(Drawable d, int verticalAlignment) {
...
}
public ImageSpan(Context context, Bitmap b, int verticalAlignment) {
...
}
public void setSpan(Object what, int start, int end, int flags) {
...
}
注意:
1、verticalAlignment有两个值:
ALIGN_BOTTOM:和baseline下面的descender对齐
ALIGN_BASELINE:和text的baseline对齐
默认是ALIGN_BOTTOM。
2、spannableString的setSpan:
what:这里传入样式,如:ImageSpan等
start:样式作用在文本的起始点(产生的作用包括该点,从0开始)
end:样式作用在文本的结束点(产生的作用不包括该点,从0开始)
flags:是否包含start或者end点的字符
flags的选项在Spanned接口中,分别为:
SPAN_INCLUSIVE_EXCLUSIVE:包含start,不包含end
SPAN_INCLUSIVE_INCLUSIVE:start,end都包含
SPAN_EXCLUSIVE_EXCLUSIVE:start,end都不包含
SPAN_EXCLUSIVE_INCLUSIVE:start不包含,end包含
使用如下:
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resId, options);
ImageSpan imageSpan = new ImageSpan(context,bitmap);
//将start到end之间的字符替换成目标图片
spannableString.setSpan(imageSpan, start, end,Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
Drawable res=context.getResources().getDrawable(R.drawable.test);
res.setBounds(0,0,res.getIntrinsicWidth(),res.getIntrinsicHeight());
ImageSpan span=new ImageSpan(res,ImageSpan.ALIGN_BOTTOM);
//ForegroundColorSpan span=new ForegroundColorSpan(resColor);
spannableString.setSpan(span,start,end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
return spannableString;
代码如下:
public SpannableString getSpannableString(Context context,String str){
initBitmapOption(context);
try {
dealExpression(context, str);
} catch (Exception e) {
Log.e("dealExpression", e.getMessage());
}
return spannableString;
}
private void dealExpression(Context context,String str) {
SpannableString spannableString=new SpannableString(str);
// 正则表达式比配字符串里是否含有表情,如: 我好[开心]啊
String zhengze = "\\[[^\\]]+\\]";
// 通过传入的正则表达式来生成一个pattern
Pattern pattern = Pattern.compile(zhengze, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(spannableString);
while (matcher.find()) {
String key = matcher.group();
if(AppUtil.getInstance().getFaceMapHX().containsKey(key)){
int resId = AppUtil.getInstance().getFaceMapHX().get(key);
if (resId != 0) {
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resId, options);
if(bitmap!=null){
WeakReference weakReference=new WeakReference<>(bitmap);
// 通过图片资源id来得到bitmap,用一个ImageSpan来包装
ImageSpan imageSpan = new ImageSpan(context,weakReference.get());
// 计算该图片名字的长度,也就是要替换的字符串的长度
int end = matcher.start() + key.length();
// 将该图片替换字符串中规定的位置中
spannableString.setSpan(imageSpan, matcher.start(), end,
Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
}
}
}
}
}
private void initFaceMapHX() {
mFaceMapHX.put("[):]", R.drawable.hx_1);
...
}
3、定义表情键盘
通过在工具类中建立
private Map mFaceMap = new LinkedHashMap();
public Map getFaceMap() {
if (!mFaceMap.isEmpty())
return mFaceMap;
mFaceMap.put("[):]", R.drawable.hx_1);
...
return mFaceMap;
}
1、表情键盘的布局文件
表情键盘
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffffff"
android:orientation="vertical">
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:background="@drawable/shape_take_photo"
android:orientation="horizontal">
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1">
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="48dp"
android:text=""
android:maxLines="3"
android:gravity="center_vertical"
android:background="@drawable/char_bottombar_input_selector"
android:paddingRight="40dp"/>
android:id="@+id/showFace"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_gravity="center_vertical|right"
android:paddingBottom="10dp"
android:paddingTop="10dp"
android:src="@drawable/chat_bottombar_icon_face_selector"/>
android:id="@+id/viewPagerInfo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:visibility="gone">
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="150dp"/>
android:id="@+id/indicator"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"/>
2、自定义ViewGroup,初始化刚刚的布局文件,为VIewPager指定adapter
将所有表情图片的名称,存到keyList中(备用)
使用GridVIew填充ViewPager
使用资源图片填充GridView,为其adapter传入currentPage,能够在其中得到当前页资源图片ID
添加点击事件
代码如下:
public class FaceContainerView extends LinearLayout {
//存储表情字符名称,如[开心]
private ArrayList keyList;
//view是每一页,
private ArrayList faceViews;
...
public FaceContainerView(Context context, AttributeSet attrs, int defStyleAttr) {
...
keyList=new ArrayList<>();
//得到表情字符名称
if(AppUtil.getInstance().getFaceMap()!=null){
Set keySet= AppUtil.getInstance().getFaceMap().keySet();
if(!keySet.isEmpty()){
keyList.addAll(keySet);
}
}
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
...
//初始化表情键盘
initFaceView();
}
private void initFaceView() {
faceViews=new ArrayList<>();
//NUM_PAGE:页数,一页的图片数=7*3-1
for(int index=0;index< AppUtil.getInstance().NUM_PAGE;index++){
faceViews.add(getGridView(index));
}
FacePagerAdapter facePagerAdapter =new FacePagerAdapter(faceViews);
viewPager.setAdapter(facePagerAdapter);
viewPager.setCurrentItem(currentPage);
indicator.setViewPager(viewPager);
indicator.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
...
});
...
}
private View getGridView( int page) {
GridView gridView=new GridView(context);
gridView.setNumColumns(7);
...
FaceAdapter faceAdapter=new FaceAdapter(context, page);
gridView.setAdapter(faceAdapter);
...
return gridView;
}
}
GridView的adapter
public class FaceAdapter extends BaseAdapter {
//当前页
private int currentPage;
//所有的列表
private Map faceMap ;
//所有的资源ID
private ArrayList imageRes=new ArrayList<>();
...
public FaceAdapter(Context context, int currentPage) {
...
faceMap= AppUtil.getInstance().getFaceMapHX();
initDate();
}
private void initDate() {
if(faceMap!=null){
for(Map.Entry entry:faceMap.entrySet()){
imageRes.add(entry.getValue());
}
}
}
@Override
public int getCount() {
return AppUtil.getInstance().NUM + 1;
}
@Override
public Object getItem(int position) {
return faceInCurrentPage.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
<...viewHolder和convertView...>
if (position == AppUtil.getInstance().NUM) {
//每一页最后那个删除图片
...
} else {
int count = AppUtil.getInstance().NUM * currentPage + position;
if (faceMap!=null && count < faceMap.size()) {
int res=imageRes.get(count);
...
} else {
viewHolder.faceIV.setImageDrawable(null);
viewHolder.faceIV.setBackgroundDrawable(null);
viewHolder.faceIV.setEnabled(false);
}
}
return convertView;
}
...
}
4、管理软键盘
1、软键盘本质是一个Dialog,可以通过windowSoftInputMode, 设置Activity主窗口与软键盘的交互模式。它包括两部分:
对Activity窗口的调整(以便腾出空间展示软键盘)
adjustUnspecified:在是默认的,系统会根据界面选择不同的模式。如果有滚动列表,默认是adjustResize;如果没有,默认是adjustPan。
adjustResize:系统总是调整屏幕的大小用以保证软键盘的显示空间( 系统没有移动布局),如果布局不可以滚动,可能会导致输入框不在视野范围内 。
adjustPan:系统会通过布局的移动,来保证用户要进行输入的输入框、肯定在用户的视野范围里面,从而让用户看到自己输入的内容。
对软键盘的状态控制,即控制软键盘是隐藏还是显示
stateUnspecified:默认的,系统会根据界面采取相应的软键盘的显示模式。
stateUnchanged:当前界面的软键盘状态,取决于上一个界面的软键盘状态,无论是隐藏还是显示。
stateHidden:软键盘总是被隐藏,不管是否有输入的需求。
stateAlwaysHidden:软键盘总是被隐藏,和stateHidden不同的是,当我们跳转到下个界面,如果下个页面的软键盘是显示的,而我们再次回来的时候,软键盘就会隐藏起来。
stateVisible:软键盘总是可见的,即使在界面上没有输入框的情况下也可以强制弹出来出来。
stateAlwaysVisible:软键盘总是可见的,和stateVisible不同的是,当我们跳转到下个界面,如果下个页面软键盘是隐藏的,而我们再次回来的时候,软键盘就会显示出来。
adjustPan
adjustResize
adjustResize,可以调整屏幕的大小,可以实现软键盘顶起页面的效果
代碼如下:
xmlns:...
android:orientation="vertical"
android:fitsSystemWindows="true">
android:hint="one"
android:id="@+id/editText3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="20dp"
android:layout_weight="1"/>
android:id="@+id/btn"
android:text="下一页"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
adjustResize,实现软键盘顶起页面的效果
但是再activity背景透明的情况下,如果模式为 adjustResize ,会再切换键盘的瞬间,显示前一个页面,使用 adjustPan就不会。
2、在隐藏软键盘的时候,可以传入一个ResultReceiver对象。
这个对象需要传入一个Handler,作用是控制回调函数执行在创建Handler的线程。如果这个Handler是null,则回调会在主线程执行。
通过传入ResultReceiver对象,就可以实现,在输入法键盘隐藏之后,回调onReceiveResult,显示表情键盘:
在输入法键盘隐藏之后,显示表情键盘
InputMethodManager inputMethodManager= (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(editText.getWindowToken(), 0, new ResultReceiver(null){
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
...
}
});
关于.9图片
Android键盘自定义表情包,关于自定义表情键盘...相关推荐
- 学计算机轻松的表情包,轻松的表情包
1.[图]如何抠图表情?照片抠图表情包的教程 表情包是大家在社交网上表达情感的一种方式,通常以图片的形式出现,已经形成了一种流行文化.在这样一个表情包横行的时代,没有几张趁手的表情包都不知道怎么跟大家 ...
- 打蚊子表情包_蚊子表情包 - 蚊子微信表情包 - 蚊子QQ表情包 - 发表情 fabiaoqing.com...
为什么蚊子只爱我 - 蚊子表情包_蚊子表情 拍打蚊子GIF - 蚊子表情包_蚊子表情 采访蚊子 请问你为什么要咬我 - 蚊子表情包_蚊子表情 蚊子飞在屎上 - 打屎打屎_屎_蚊子表情 我想,最爱我的是 ...
- 暴走gif失落的出处_暴走gif表情包 - 暴走gif微信表情包 - 暴走gifQQ表情包 - 发表情 fabiaoqing.com...
我什么都不在乎-暴走漫画嘲讽搞笑表情 - 暴走漫画嘲讽搞笑表情_暴走_嘲讽_搞笑_系列表情 因为我美就要欺负我吗-暴走漫画嘲讽搞笑表情 - 暴走漫画嘲讽搞笑表情_暴走_嘲讽_搞笑_系列表情 你把智商上 ...
- 如何利用PS设计表情包和动态表情图
[UI公开课]如何利用PS设计表情包和动态表情图 课程简介: 本节课重点讲解表情包设计和经典实用案例设计. 1.图形设计软件介绍:2.网络暴漫表情包设计:3.原创表情包设计:4.GIF动态表情设计 开 ...
- Web 4U[02]-自定义表情包神器:表情锅
今日推荐:表情锅 类型:奇趣网站 网址:https://sorry.xuty.tk/ 表情包是斗图界的核武器.在这个大家越来越不爱说话的年代,表情包的使用率倒是越来越高.蘑菇头,熊猫人等传统IP历久 ...
- python从入门到入土表情包-Python开发个人专属表情包网站,表情在手,天下我有...
"表情包"是一种利用图片来表示感情的一种方式.表情包是在社交软件活跃之后,形成的一种流行文化,表情包流行于互联网上面,基本人人都会发表情. 曾经你是否也有过找不到表情包去应对别人的 ...
- python恶搞表情包-Python开发个人专属表情包网站,表情在手,天下我有
"表情包"是一种利用图片来表示感情的一种方式.表情包是在社交软件活跃之后,形成的一种流行文化,表情包流行于互联网上面,基本人人都会发表情. 曾经你是否也有过找不到表情包去应对别人的 ...
- php代码画表情包,canvas绘制表情包的示例代码
本文介绍了canvas绘制表情包的示例代码,分享给大家,具体如下: 绘制卡通笑脸 var canvas = document.getElementById('canvas'); var context ...
- python恶搞表情包-关于python表情包
广告关闭 2017年12月,云+社区对外发布,从最开始的技术博客到现在拥有多个社区产品.未来,我们一起乘风破浪,创造无限可能. 来源:python开发id:pythonpush作为一个数据分析师,应该 ...
- 我要学计算机表情包,确认过表情包,怕是遇上学计算机的“同道中人”了
不同的大学专业有着自己的专属表情包,专业知识结合着骚浪贱,皮中带稳还多了点内涵--今天我们来围(bi)观(pin)计算机科学 CS 专业学生才能懂的表情包. 说到计算机, 不禁想起被亲朋好友问专业时的 ...
最新文章
- android对OnTouchListener、OnClickListener等事件响应的研究
- 【转蝈蝈俊.net 】SQL Server 2005 配置发送邮件
- 国内大数据开发中比较受欢迎的几款工具
- c语言建立线性表(顺序储存,链式储存,循环,双向)全
- 朴素贝叶斯方法(Naive Bayes)原理和实现
- 【Manacher】【贪心】字符串连接(金牌导航 Manacher-4)
- Github项目汇总
- 险些被吓到!白宇代言新品万元荣耀8X售价原因揭秘
- 在linux下的vsftp的使用
- NPM酷库050:xmlbuilder,创建XML文件
- CEC2018:动态多目标测试函数DF1~DF5的PS及PF
- 读《Redis入门指南》2
- 八、python爬虫伪装 [免费伪装ip伪装请求头]
- 解决黑苹果无法自动更新的问题,
- php 半角 全角空格,全角空格和半角空格
- 抖音小店入驻条件及费用最新版,2022抖音开店,商家入门指南
- XMPP 协议的原理和介绍
- 百万册热销书《考试脑科学》续作!每个家长都应该买的一本书
- Android Fota(差分包)制作
- Unity使用波函数坍缩 (Wave Collapse Function)算法生成随机地图
热门文章
- 基于Django搭建Python web项目——项目创建及配置(一)
- cad考试题库绘图题答案_CAD考试试题库和参考答案解析
- BUUCTF-Misc-No.4
- 数据库SQL Server 如何将数据库表名等前缀转换成dbo
- 如何回复客户英文邮件
- excel调查问卷的录入
- python中numpy函数ftt_语音MFCC提取:librosa python_speech_feature(2019.12)
- 阿里CTO王坚:商业进化的四个关键词
- cpu第几代计算机,赛扬G系列有几代cpu分别是
- JavaScript 数据结构与算法(队列)