失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Android-仿QQ表情库 表情混合文字聊天图文

Android-仿QQ表情库 表情混合文字聊天图文

时间:2021-08-21 14:15:38

相关推荐

Android-仿QQ表情库 表情混合文字聊天图文

实现仿QQ表情库。点击表情转换为对应特殊字符串放入EditText,在消息列表中将特殊字符串转换为表情。

效果演示:

一、实现QQ表情库

1. 导入表情库图片放在assets文件夹里

2. 全局首次加载这个图片,使用集合存储起来。关联图片和文字

在Application中加载表情对应文字数组、表情对应图文集合

// 图片&字符串对应关系public static HashMap<String,String> biaoqingMap = new HashMap();public static String[] biaoqingStringList = new String[]{"[惊讶]","[撇嘴]","[色]","[发呆]","[得意]","[流泪]","[害羞]","[闭嘴]","[睡]","[大哭]","[尴尬]","[发怒]","[调皮]","[呲牙]","[微笑]","[难过]", "[哭]", "[非典]","[抓狂]", "[吐]", "[偷笑]", "[可爱]", "[白眼]", "[傲慢]", "[饥饿]", "[酷]", "[惊恐]", "[流汗]", "[憨笑]", "[大兵]", "[奋斗]", "[咒骂]", "[疑问]", "[嘘]", "[晕]","[折磨]", "[衰]", "[骷髅]", "[捶打]", "[再见]", "[闪人]", "[发抖]", "[爱情]", "[跳]", "[找]", "[美眉]", "[猪头]", "[猫咪]", "[小狗]", "[拥抱]", "[钱]", "[灯泡]","[酒杯]", "[蛋糕]", "[闪电]", "[炸弹]", "[刀]", "[足球]", "[音乐]", "[便便]", "[咖啡]", "[饭]", "[药丸]", "[玫瑰]", "[凋谢]", "[吻]", "[爱心]", "[心碎]", "[会议]","[礼物]", "[电话]", "[时间]", "[邮件]", "[电视]", "[太阳]", "[月亮]", "[强]", "[弱]", "[握手]", "[胜利]"};private void initBiaoqingMap() {biaoqingMap.put("[惊讶]", "ic_01_jinya.gif");biaoqingMap.put("[撇嘴]", "ic_02_beizui.gif");biaoqingMap.put("[色]", "ic_03_se.gif");biaoqingMap.put("[发呆]", "ic_04_fadai.gif");biaoqingMap.put("[得意]", "ic_05_deyi.gif");biaoqingMap.put("[流泪]", "ic_06_liulei.gif");biaoqingMap.put("[害羞]", "ic_07_haixiu.gif");biaoqingMap.put("[闭嘴]", "ic_08_bizui.gif");biaoqingMap.put("[睡]", "ic_09_shui.gif");biaoqingMap.put("[大哭]", "ic_10_daku.gif");biaoqingMap.put("[尴尬]", "ic_11_ganga.gif");biaoqingMap.put("[发怒]", "ic_12_fanu.gif");biaoqingMap.put("[调皮]", "ic_13_tiaopi.gif");biaoqingMap.put("[呲牙]", "ic_14_ciya.gif");biaoqingMap.put("[微笑]", "ic_15_weixiao.gif");biaoqingMap.put("[难过]", "ic_16_nanguo.gif");biaoqingMap.put("[哭]", "ic_17_ku.gif");biaoqingMap.put("[非典]", "ic_18_feidian.gif");biaoqingMap.put("[抓狂]", "ic_19_zhuakuang.gif");biaoqingMap.put("[吐]", "ic_20_tu.gif");biaoqingMap.put("[偷笑]", "ic_21_touxiao.gif");biaoqingMap.put("[可爱]", "ic_22_keai.gif");biaoqingMap.put("[白眼]", "ic_23_baiyan.gif");biaoqingMap.put("[傲慢]", "ic_24_aoman.gif");biaoqingMap.put("[饥饿]", "ic_25_jie.gif");biaoqingMap.put("[酷]", "ic_26_kun.gif");biaoqingMap.put("[惊恐]", "ic_27_jingkong.gif");biaoqingMap.put("[流汗]", "ic_28_liuhan.gif");biaoqingMap.put("[憨笑]", "ic_29_hanxiao.gif");biaoqingMap.put("[大兵]", "ic_30_dabing.gif");biaoqingMap.put("[奋斗]", "ic_31_fengdou.gif");biaoqingMap.put("[咒骂]", "ic_32_zhouma.gif");biaoqingMap.put("[疑问]", "ic_33_yiwen.gif");biaoqingMap.put("[嘘]", "ic_34_xu.gif");biaoqingMap.put("[晕]", "ic_35_yun.gif");biaoqingMap.put("[折磨]", "ic_36_zhemo.gif");biaoqingMap.put("[衰]", "ic_37_shuai.gif");biaoqingMap.put("[骷髅]", "ic_38_kulou.gif");biaoqingMap.put("[捶打]", "ic_39_chuida.gif");biaoqingMap.put("[再见]", "ic_40_zaijian.gif");biaoqingMap.put("[闪人]", "ic_41_shangren.gif");biaoqingMap.put("[发抖]", "ic_42_fadou.gif");biaoqingMap.put("[爱情]", "ic_43_aiqing.gif");biaoqingMap.put("[跳]", "ic_44_tiao.gif");biaoqingMap.put("[找]", "ic_45_zhao.gif");biaoqingMap.put("[美眉]", "ic_46_meimei.gif");biaoqingMap.put("[猪头]", "ic_47_zhutou.gif");biaoqingMap.put("[猫咪]", "ic_48_maomi.gif");biaoqingMap.put("[小狗]", "ic_49_xiaogou.gif");biaoqingMap.put("[拥抱]", "ic_50_yongbao.gif");biaoqingMap.put("[钱]", "ic_51_qian.gif");biaoqingMap.put("[灯泡]", "ic_52_dengpao.gif");biaoqingMap.put("[酒杯]", "ic_53_jiubei.gif");biaoqingMap.put("[蛋糕]", "ic_54_danggao.gif");biaoqingMap.put("[闪电]", "ic_55_shangdian.gif");biaoqingMap.put("[炸弹]", "ic_56_zhadang.gif");biaoqingMap.put("[刀]", "ic_57_dao.gif");biaoqingMap.put("[足球]", "ic_58_zuqiu.gif");biaoqingMap.put("[音乐]", "ic_59_yinyue.gif");biaoqingMap.put("[便便]", "ic_60_bianbian.gif");biaoqingMap.put("[咖啡]", "ic_61_kafei.gif");biaoqingMap.put("[饭]", "ic_62_fan.gif");biaoqingMap.put("[药丸]", "ic_63_yaowan.gif");biaoqingMap.put("[玫瑰]", "ic_64_meigui.gif");biaoqingMap.put("[凋谢]", "ic_65_diaoxie.gif");biaoqingMap.put("[吻]", "ic_66_wen.gif");biaoqingMap.put("[爱心]", "ic_67_aixin.gif");biaoqingMap.put("[心碎]", "ic_68_xinsui.gif");biaoqingMap.put("[会议]", "ic_69_huiyi.gif");biaoqingMap.put("[礼物]", "ic_70_liwu.gif");biaoqingMap.put("[电话]", "ic_71_dianhua.gif");biaoqingMap.put("[时间]", "ic_72_shijian.gif");biaoqingMap.put("[邮件]", "ic_73_youjian.gif");biaoqingMap.put("[电视]", "ic_74_dianshi.gif");biaoqingMap.put("[太阳]", "ic_75_taiyang.gif");biaoqingMap.put("[月亮]", "ic_76_yueliang.gif");biaoqingMap.put("[强]", "ic_77_qiang.gif");biaoqingMap.put("[弱]", "ic_78_ruo.gif");biaoqingMap.put("[握手]", "ic_79_woshou.gif");biaoqingMap.put("[胜利]", "ic_80_shengli.gif");}

3. 实现表情列表

xml文件:

<android.support.v7.widget.RecyclerViewandroid:id="@+id/gv_face"android:layout_width="match_parent"android:layout_height="150dp"android:background="@color/content_dark_bg"android:scrollbars="none"android:overScrollMode="ifContentScrolls"android:paddingLeft="10dp"android:paddingRight="10dp"android:visibility="gone"/>

item_faceimage_channel.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/apk/res/android"android:orientation="vertical"android:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="5dp"><ImageViewandroid:id="@+id/iv_face"android:layout_width="20dp"android:layout_height="20dp"/></LinearLayout>

自定义点击事件监听回调:

public interface MyItemOnClickListener {public void onItemOnClick(View view, int postion);}

Grid适配器

public class FaceImageGridAdapter extends RecyclerView.Adapter<FaceImageGridAdapter.FaceImageViewHolder> {private String[] wechatemojis;private Context mContext;private MyItemOnClickListener mListener;public FaceImageGridAdapter(Context context, String[] list){this.mContext = context;this.wechatemojis = list;}public void setItemOnClickListener(MyItemOnClickListener listener){mListener=listener;}@NonNull@Overridepublic FaceImageViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {return new FaceImageViewHolder(LayoutInflater.from(mContext).inflate(R.layout.item_faceimage_channel,parent,false),mListener);}@Overridepublic void onBindViewHolder(@NonNull FaceImageViewHolder holder, int position) {//依次加载assets表情图片InputStream is = null;try {is = mContext.getResources().getAssets().open("qqface/"+wechatemojis[position]);} catch (IOException e) {e.printStackTrace();}Bitmap bitmap = BitmapFactory.decodeStream(is);holder.iv_face.setImageBitmap(bitmap);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic int getItemCount() {return wechatemojis.length;}class FaceImageViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {protected ImageView iv_face;public FaceImageViewHolder(@NonNull View itemView,MyItemOnClickListener myItemOnClickListener) {super(itemView);iv_face = (ImageView) itemView.findViewById(R.id.iv_face);iv_face.setOnClickListener(this);}@Overridepublic void onClick(View v) {if(mListener!=null){mListener.onItemOnClick(itemView,getPosition());}}}}

初始化RecyclerView

private void initBaioqing(){try {wechatemojis = getResources().getAssets().list("qqface");faceImageGridAdapter = new FaceImageGridAdapter(getApplicationContext(),wechatemojis);faceImageGridAdapter.setItemOnClickListener(new MyItemOnClickListener() {@Overridepublic void onItemOnClick(View view, int postion) {//点击了表情if(TextUtils.isEmpty(etInput.getText().toString().trim())){etInput.setText(biaoqingStringList[postion]);}else{//光标处插入表情字符int index = etInput.getSelectionStart();Editable editable = etInput.getText();editable.insert(index,biaoqingStringList[postion]);}}});gvFace.setLayoutManager(new GridLayoutManager(InstantMessageActivity.this,8));gvFace.setAdapter(faceImageGridAdapter);} catch (IOException e) {e.printStackTrace();}}

二、图文混合展示

1. 通过自定义控件将特殊字符串转图片

@SuppressLint("AppCompatCustomView")public class BiaoQingTextView extends TextView {public BiaoQingTextView(Context context) {super(context);}public BiaoQingTextView(Context context, AttributeSet attrs) {super(context, attrs);}public BiaoQingTextView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}public void initView(Context context){String str = getText().toString();if(str==null||"".equals(str)) {this.setText("");return;}try{InputStream bitmap=null;SpannableString ss = new SpannableString(str);Bitmap bit=null;//处理显示表情String content = str;int len = 0;int starts = 0;int end = 0;while(len < content.length()){if(content.indexOf("[", starts) != -1 && content.indexOf("]", end) != -1){starts = content.indexOf("[", starts);end = content.indexOf("]", end);String phrase = content.substring(starts,end + 1);String value = biaoqingMap.get(phrase);try {bitmap = context.getResources().getAssets().open("qqface/" + value);bit= BitmapFactory.decodeStream(bitmap);} catch (IOException e) {e.printStackTrace();}Drawable drawable = new BitmapDrawable(bit);try {if (drawable != null) {drawable.setBounds(0, 0, 45, 45);VerticalImageSpan span = new VerticalImageSpan(drawable);ss.setSpan(span, starts,end + 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);}} catch (SecurityException e) {e.printStackTrace();}starts = end;len = end;end++;}else{starts++;end++;len = end;}}this.setText(ss);} catch (Exception e) {e.printStackTrace();}}}

2. 处理对齐

public class VerticalImageSpan extends ImageSpan {public VerticalImageSpan(Drawable drawable) {super(drawable);}@Overridepublic int getSize(Paint paint, CharSequence text, int start, int end,Paint.FontMetricsInt fontMetricsInt) {Drawable drawable = getDrawable();Rect rect = drawable.getBounds();if (fontMetricsInt != null) {Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt();int fontHeight = fmPaint.bottom - fmPaint.top;int drHeight = rect.bottom - rect.top;int top = drHeight / 2 - fontHeight / 4;int bottom = drHeight / 2 + fontHeight / 4;fontMetricsInt.ascent = -bottom;fontMetricsInt.top = -bottom;fontMetricsInt.bottom = top;fontMetricsInt.descent = top;}return rect.right;}@Overridepublic void draw(Canvas canvas, CharSequence text, int start, int end,float x, int top, int y, int bottom, Paint paint) {Drawable drawable = getDrawable();canvas.save();int transY = 0;transY = ((bottom - top) - drawable.getBounds().bottom) / 2 + top;canvas.translate(x, transY);drawable.draw(canvas);canvas.restore();}}

问题1:键盘自带的emoji表情无法作为内容上传

原因是MySQL数据库存入不了表情符号

解决:对内容进行Base64加密再上传,获取时解密后再展示。

// 加密String str_count= Base64.encodeToString(str_count.getBytes(),Base64.DEFAULT);// 解密byte[] bytes=Base64.decode(this.bean.getContent(),Base64.DEFAULT);holder.content.setText(new String(bytes));

参考文章:

/qq_37210413/article/details/113701344

/qq_22230935/article/details/54927304

/suncold123/article/details/69663258

如果觉得《Android-仿QQ表情库 表情混合文字聊天图文》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。