Android实用视图动画及工具系列之六:通用表情栏,仿QQ微信聊天弹出表情选框
16lz
2021-01-26
实现效果
功能说明
仿QQ微信聊天表情库框,这个目前市面上已经很多类似的功能了,我就不做多的累赘,本表情栏的优势在于便于集成,而且适用于多种环境,可转换为html标签和转义表情标签等,由于总体代码和资源较少,集成方便,就未上传jcenter或Maven central上了,需要用到类似功能的自行下载源码集成到项目中即可。 适用于新手及新学习Android的码友们,老玩家当然也可以看看,这个还是挺简单挺实用的,在后面会简略介绍实现方法及源代码,同时博客的最后还提供源代码和图片等资源github下载地址。本部分内容主要讲解表情栏实现,不讲解底部弹出框的实现,需要查看底部弹出框部分实现的请查看这篇文章: --------------------------------------------------------------------------------------------------------------------
Android实用视图动画及工具系列之五:底部回复对话框,仿QQ空间微信朋友圈回复对话框: http://blog.csdn.net/jaikydota163/article/details/52098869 --------------------------------------------------------------------------------------------------------------------
功能讲解
一:项目结构和外观样式
既然是表情库就需要表情,可以是本地的,也可以是从网络加载的,看需求更改,本例子提供了一些本地表情包:(其他图片资源在源代码内,需要的自行下载):项目结构如下,总共5个类,一些表情和两个布局文件,还是很简约的:
二:部分代码详解
主类为FaceView.class,主要完成了表情的布局,适配,和转义功能,提供了两种模式: 转义为标签或转义为表情标签,如“/e002”,约定一个转义规则。 转义为表情标签的方法为getImgTag(); 转换为标签修改imgTag即可。private static String imgTag = "\"http://www.host.com/images/-1.png\" border=\"0\" alt=\"\"/>";
//mode , html tag or escape tagpublic static int TAG_MODE_IMG = 1;public static int TAG_MODE_EMOJI = 2;
package com.jaiky.test.faceview;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Color;import android.graphics.drawable.BitmapDrawable;import android.graphics.drawable.ColorDrawable;import android.graphics.drawable.Drawable;import android.support.v4.view.ViewPager;import android.support.v4.view.ViewPager.OnPageChangeListener;import android.text.Spannable;import android.text.SpannableString;import android.text.style.ImageSpan;import android.util.AttributeSet;import android.util.DisplayMetrics;import android.util.TypedValue;import android.view.Gravity;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.view.View.OnClickListener;import android.view.ViewGroup;import android.view.inputmethod.InputMethodManager;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.EditText;import android.widget.GridView;import android.widget.ImageView;import android.widget.LinearLayout;import java.util.ArrayList;import java.util.List;public class FaceView extends LinearLayout implements OnPageChangeListener,OnItemClickListener, OnClickListener {/** * Convert to Html Tag, using for webPage */private static String imgTag = "";/** * Face size */private int faceDefaultSize = 17;private List m_arrFacePageView;private ViewPager m_vpFace;private List m_arrDotView;private LinearLayout m_dotBar;private Context m_context;private OnFaceSelectedListener m_listener;private EditText m_edit;private View m_btnView;private int m_tagMode;//mode , html tag or escape tagpublic static int TAG_MODE_IMG = 1;public static int TAG_MODE_EMOJI = 2;private int faceStyleResource;private int textStyleResource;/** * 实例化方法 * * @param context * @param attrs */public FaceView(Context context, AttributeSet attrs) {super(context, attrs);m_context = context;m_tagMode = TAG_MODE_IMG;LayoutInflater.from(context).inflate(R.layout.global_face_view, this, true);initView();}// 设置标签模式public void setTagMode(int tagMode) {m_tagMode = tagMode;}/** * set the button of show or hide the faceview * * @param btnView * @author saderos * */public void setBtnView(View btnView) {m_btnView = btnView;m_btnView.setOnClickListener(this);}public void setFaceAndTextStyle(int faceStyle, int textStyle){this.faceStyleResource = faceStyle;this.textStyleResource = textStyle;}/** * if you just need to set the editText, and them ,you don't have to append * text to the editText yourself * * @author saderos * @param editText */public void setEdit(EditText editText) {m_edit = editText;m_edit.setOnTouchListener(new OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {if (event.getAction() == MotionEvent.ACTION_DOWN) {FaceView.this.setVisibility(View.GONE);setShowImageResource();}return false;}});}public void setHideToggle(View v) {v.setOnTouchListener(new OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {if (event.getAction() == MotionEvent.ACTION_DOWN) {FaceView.this.setVisibility(View.GONE);setShowImageResource();}return false;}});}public void setOnFaceSelectedListener(OnFaceSelectedListener listener) {m_listener = listener;}/** * 初始化视图 */private void initView() {if (isInEditMode()) {return;}m_vpFace = (ViewPager) findViewById(R.id.chat_vpFace);m_dotBar = (LinearLayout) findViewById(R.id.chat_dotbar);initFaceBar();}private void initFaceBar() {m_arrFacePageView = new ArrayList();for (int i = 0; i < 9; i++) {GridView view = new GridView(m_context);FaceAdapter adapter = new FaceAdapter(m_context, i);view.setOnItemClickListener(this);view.setAdapter(adapter);view.setNumColumns(7);view.setBackgroundColor(Color.TRANSPARENT);view.setHorizontalSpacing(1);view.setVerticalSpacing(1);view.setStretchMode(GridView.STRETCH_COLUMN_WIDTH);view.setCacheColorHint(0);view.setSelector(new ColorDrawable(Color.TRANSPARENT));view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT));view.setGravity(Gravity.CENTER);m_arrFacePageView.add(view);}ViewPagerAdapter adapter = new ViewPagerAdapter(m_arrFacePageView);if (!isInEditMode()) {m_vpFace.setAdapter(adapter);m_vpFace.setCurrentItem(1);}m_vpFace.setOnPageChangeListener(this);initDotBar();}private void initDotBar() {m_arrDotView = new ArrayList();if (m_arrFacePageView.size() <= 3)return;for (int i = 0; i < m_arrFacePageView.size() - 2; i++) {ImageView imgView = new ImageView(m_context);imgView.setBackgroundResource(R.drawable.common_indicator_nor);LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));DisplayMetrics dm = getResources().getDisplayMetrics();params.leftMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, dm);params.rightMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, dm);// params.width = 7;// params.height = 7;m_dotBar.addView(imgView, params);m_arrDotView.add(imgView);}setSelDot(0);}private void setSelDot(int nSelIndex) {for (int i = 0; i < m_arrDotView.size(); i++) {if (nSelIndex == i) {m_arrDotView.get(i).setBackgroundResource(R.drawable.common_indicator_checked);} else {m_arrDotView.get(i).setBackgroundResource(R.drawable.common_indicator_nor);}}}@Overridepublic void onPageSelected(int arg0) {if (0 == arg0) {m_vpFace.setCurrentItem(arg0 + 1);} else if (arg0 == m_arrFacePageView.size() - 1) {m_vpFace.setCurrentItem(arg0 - 1);} else {setSelDot(arg0 - 1);}}@Overridepublic void onItemClick(AdapterView<?> arg0, View v, int arg2, long arg3) {View img = v.findViewById(R.id.facelistitem_imgFace);String selImgTag = "";int id = Integer.parseInt(img.getTag().toString());if (m_tagMode == TAG_MODE_IMG) {selImgTag = imgTag.replace("-1", id + "");} else {selImgTag = getImgTag(id);}Bitmap bitmap = BitmapFactory.decodeResource(getResources(),FaceManager.getInstance().getFace(id));if (m_listener != null) {m_listener.OnFaceSelected(selImgTag, bitmap);}if (m_edit != null) {Drawable drawable=new BitmapDrawable(m_context.getResources(),bitmap);int size = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, faceDefaultSize, getResources().getDisplayMetrics());drawable.setBounds(0, 0, size, size);ImageSpan imgSpan = new ImageSpan(drawable);SpannableString spanString = new SpannableString(selImgTag);spanString.setSpan(imgSpan, 0, spanString.length(),Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);m_edit.append(spanString);}}public interface OnFaceSelectedListener {public void OnFaceSelected(String imgTag, Bitmap face);}@Overridepublic void onPageScrollStateChanged(int arg0) {}@Overridepublic void onPageScrolled(int arg0, float arg1, int arg2) {}@Overridepublic void onClick(View v) {// 点击输入框,则隐藏表情if (v == m_btnView) {InputMethodManager imm = (InputMethodManager) m_context.getSystemService(Context.INPUT_METHOD_SERVICE);if (this.getVisibility() == View.GONE) {imm.hideSoftInputFromWindow(getApplicationWindowToken(),InputMethodManager.HIDE_NOT_ALWAYS);try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}this.setVisibility(View.VISIBLE);} else {imm.showSoftInput(m_edit, InputMethodManager.SHOW_IMPLICIT);this.setVisibility(View.GONE);}setShowImageResource();}}private void setShowImageResource() {if (textStyleResource == 0 || faceStyleResource == 0) {//设置默认显示if (m_btnView instanceof ImageView) {if (getVisibility() == View.GONE)((ImageView)m_btnView).setImageResource(R.drawable.chatform_face_selector);else((ImageView)m_btnView).setImageResource(R.drawable.chatform_setmodetext_selector);}}else {if (getVisibility() == View.GONE)m_btnView.setBackgroundResource(faceStyleResource);elsem_btnView.setBackgroundResource(textStyleResource);}}private String getImgTag(int position) {String imgTag = "";// the number of total image is 134,so when the image number larger than// 134 ,them return nullif (position > 134)return null;imgTag = position + "";switch (imgTag.length()) {case 1:imgTag = "/e00" + imgTag;break;case 2:imgTag = "/e0" + imgTag;break;case 3:imgTag = "/e" + imgTag;break;default:break;}return imgTag;}}
二:使用表情库
使用比较简单,在布局文件中添加:
在代码中添加:
//此处绑定表情栏FaceView faceView = (FaceView) findViewById(R.id.face_view);//表情的编辑框EditTextfaceView.setEdit(etContent);//弹出表情库的按钮faceView.setBtnView(ivFace);
设置显示的TextView:
TextView.setText(Html.fromHtml(replyDialog.getContent(), new FaceImageGetter(context), null));
--------------------------------------------------------------------------------------------------------------------
获取源代码及资源文件: https://github.com/jaikydota/Android-FaceView
--------------------------------------------------------------------------------------------------------------------
声明
欢迎转载,但请保留文章原始出处
作者:Jaiky_杰哥
出处:http://blog.csdn.net/jaikydota163/article/details/52098873
更多相关文章
- android系统自带Emoji表情与表情描述互相转换
- Android(安卓)UI设计之使用HTML标签,实现在TextView中对中文文字
- (转摘)Android腾讯微博客户端开发四:微博发送篇(QQ表情,@搜索)
- Android(安卓)NFC API Reference中英文
- Android——View.setTag()
- android获取网页数据的几种方式
- Android过滤特殊字符和emoji表情
- Android中过滤Emoji表情 完整版
- Android(安卓)流式布局(标签效果)