原地址:http://blog.csdn.net/jaikydota163/article/details/52098873?locationNum=10&fps=1
实现效果
仿QQ微信聊天表情库框,这个目前市面上已经很多类似的功能了,我就不做多的累赘,本表情栏的优势在于便于集成,而且适用于多种环境,可转换为html标签和转义表情标签等,由于总体代码和资源较少,集成方便,就未上传jcenter或Maven central上了,需要用到类似功能的自行下载源码集成到项目中即可。
适用于新手及新学习Android的码友们,老玩家当然也可以看看,这个还是挺简单挺实用的,在后面会简略介绍实现方法及源代码,同时博客的最后还提供源代码和图片等资源github下载地址。
本部分内容主要讲解表情栏实现,不讲解底部弹出框的实现,需要查看底部弹出框部分实现的请查看这篇文章:
--------------------------------------------------------------------------------------------------------------------
Android实用视图动画及工具系列之五:底部回复对话框,仿QQ空间微信朋友圈回复对话框:
--------------------------------------------------------------------------------------------------------------------
一:项目结构和外观样式
既然是表情库就需要表情,可以是本地的,也可以是从网络加载的,看需求更改,本例子提供了一些本地表情包:(其他图片资源在源代码内,需要的自行下载):
项目结构如下,总共5个类,一些表情和两个布局文件,还是很简约的:
二:部分代码详解
主类为FaceView.class,主要完成了表情的布局,适配,和转义功能,提供了两种模式:
转义为<img>标签或转义为表情标签,如“/e002”,约定一个转义规则。
转义为表情标签的方法为getImgTag();
转换为<img>标签修改imgTag即可。
private static String imgTag = "<img src=\"http://www.host.com/images/-1.png\" border=\"0\" alt=\"\"/>";
//mode , html tag or escape tag
public 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 = "<img src=\"http://www.host.com/images/-1.png\" border=\"0\" alt=\"\"/>";
-
- /**
- * Face size
- */
- private int faceDefaultSize = 17;
-
- private List<View> m_arrFacePageView;
- private ViewPager m_vpFace;
- private List<ImageView> 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 tag
- public 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() {
-
- @Override
- public 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() {
-
- @Override
- public 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<View>();
- 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<ImageView>();
-
- 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);
- }
- }
- }
-
- @Override
- public 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);
- }
- }
-
- @Override
- public 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);
- }
-
- @Override
- public void onPageScrollStateChanged(int arg0) {
-
- }
-
- @Override
- public void onPageScrolled(int arg0, float arg1, int arg2) {
-
- }
-
-
- @Override
- public 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);
- else
- m_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 null
- if (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;
- }
-
- }
二:使用表情库
使用比较简单,在布局文件中添加:
- <com.jaiky.test.faceview.FaceView
- android:id="@+id/face_view"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:visibility="gone" >
- </com.jaiky.test.faceview.FaceView>
在代码中添加:
- //此处绑定表情栏
- FaceView faceView = (FaceView) findViewById(R.id.face_view);
- //表情的编辑框EditText
- faceView.setEdit(etContent);
- //弹出表情库的按钮
- faceView.setBtnView(ivFace);
设置显示的TextView:
- TextView.setText(Html.fromHtml(replyDialog.getContent(), new FaceImageGetter(context), null));
--------------------------------------------------------------------------------------------------------------------
获取源代码及资源文件:
--------------------------------------------------------------------------------------------------------------------