本Demo主要使用到了2个类MainActivity.java,EmojiAdapter.java,实现了EditText显示表情,点击 删除实现删除表情和文字,效果图如下,demo的源码在最后。
下面是MainActivity.java
package com.cool.emojidemo; import android.app.Activity; import android.content.Context; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.support.v4.view.ViewPager; import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.style.ImageSpan; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.InputMethodManager; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.RelativeLayout; import android.widget.TextView; import com.cool.emojidemo.adapter.EmojiAdapter; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; public class MainActivity extends Activity implements View.OnClickListener { private ListView mChatListView; private ImageButton mFaceImageButton; private EditText mMessageEditText; private Button mSendButton; private ViewPager mEmojiViewPager; private List<String> mMessageList = new ArrayList<String>(); private ChatAdapter mChatAdapter; private LinearLayout mPointContain; private boolean isFaceShow = false; private RelativeLayout mFaceContainRelativeLayout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // getSupportActionBar().hide();//去掉标题栏 setContentView(R.layout.activity_main); initView(); initEmoji();//初始化表情 mChatAdapter = new ChatAdapter(); mChatListView.setAdapter(mChatAdapter); } private void initView() { mChatListView = (ListView) findViewById(R.id.lv_list); mFaceImageButton = (ImageButton) findViewById(R.id.ib_face); mMessageEditText = (EditText) findViewById(R.id.et_message); mSendButton = (Button) findViewById(R.id.bt_send); mEmojiViewPager = (ViewPager) findViewById(R.id.vp_emoji); mPointContain = (LinearLayout) findViewById(R.id.ll_point_contain); mFaceContainRelativeLayout = (RelativeLayout) findViewById(R.id.rl_face_contain); mSendButton.setOnClickListener(this); mFaceImageButton.setOnClickListener(this); mMessageEditText.setOnClickListener(this); } /** * 初始化表情 */ private void initEmoji() { mEmojiViewPager.setAdapter(new EmojiAdapter(this, mMessageEditText, mEmojiViewPager, mPointContain)); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.bt_send: String message = mMessageEditText.getText().toString(); // Log.e("399", message); mMessageList.add(message); mChatAdapter.notifyDataSetChanged(); mMessageEditText.setText(""); mChatListView.setSelection(mMessageList.size()); break; case R.id.ib_face: showOrHideFace(); hideSoftInput(); break; case R.id.et_message: if(isFaceShow){ showOrHideFace(); } break; } } private void showOrHideFace() { if (isFaceShow) { mFaceContainRelativeLayout.setVisibility(View.GONE); } else { mFaceContainRelativeLayout.setVisibility(View.VISIBLE); } isFaceShow = !isFaceShow; } class ChatAdapter extends BaseAdapter { @Override public int getCount() { if (mMessageList != null && mMessageList.size() > 0) { return mMessageList.size(); } return 0; } @Override public Object getItem(int i) { return mMessageList.get(i); } @Override public long getItemId(int i) { return i; } @Override public View getView(int i, View view, ViewGroup viewGroup) { ViewHolder viewHolder; if (view == null) { view = View.inflate(MainActivity.this, R.layout.item_chat, null); viewHolder = new ViewHolder(); viewHolder.mMessageTextView = (TextView) view.findViewById(R.id.tv_message); view.setTag(viewHolder); } else { viewHolder = (ViewHolder) view.getTag(); } //将消息进行解析显示到TextView中 parseMessage(mMessageList.get(i), viewHolder.mMessageTextView); // viewHolder.mMessageTextView.setText(mMessageList.get(i)); return view; } } private void parseMessage(String s, TextView mMessageTextView) { SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(s); Pattern pattern = Pattern.compile("\\[(\\S+?)\\]");//匹配[xx]的字符串 Matcher matcher = pattern.matcher(s); while (matcher.find()) { int start = matcher.start(); int end = matcher.end(); String group = matcher.group(); group = group.substring(1, group.length() - 1); Log.e("399", group); int drawableId = getResources().getIdentifier(group, "drawable", getPackageName()); Drawable drawable = getResources().getDrawable(drawableId); int size = (int) (35 * getResources().getDisplayMetrics().density); drawable.setBounds(0, 0, size, size); ImageSpan imageSpan = new ImageSpan(drawable); spannableStringBuilder.setSpan(imageSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } mMessageTextView.setText(spannableStringBuilder, TextView.BufferType.SPANNABLE); } static class ViewHolder { TextView mMessageTextView; } private void hideSoftInput() { //1.得到InputMethodManager对象 InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); //2.调用hideSoftInputFromWindow方法隐藏软键盘 imm.hideSoftInputFromWindow(mMessageEditText.getWindowToken(), 0); //强制隐藏键盘 } private void showSoftInput(){ //1.得到InputMethodManager对象 InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); //2.调用showSoftInput方法显示软键盘,其中view为聚焦的view组件 imm.showSoftInput(mMessageEditText, InputMethodManager.SHOW_FORCED); } private boolean isSoftOpen(){ //1.得到InputMethodManager对象 InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); //获取状态信息 boolean isOpen=imm.isActive();//isOpen若返回true,则表示输入法打开 return isOpen; } }
EmojiAdapter.java
package com.cool.emojidemo.adapter; import android.content.Context; import android.graphics.Color; import android.graphics.drawable.Drawable; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.text.Editable; import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.TextUtils; import android.text.style.ImageSpan; import android.util.Log; import android.util.SparseArray; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.EditText; import android.widget.GridView; import android.widget.ImageView; import android.widget.LinearLayout; import com.cool.emojidemo.R; import java.util.ArrayList; import java.util.List; /** * Created by cool on 2016/7/22. */ public class EmojiAdapter extends PagerAdapter { private Context mContext; private EditText mMessageEditText; private ViewPager mEmojiViewPager; private LinearLayout mPointContain; private List<Integer> emojiList = new ArrayList<Integer>(); private List<GridView> mGridViewList = new ArrayList<GridView>(); private int totalPage; private SparseArray<String> mSparseArray = new SparseArray<String>(); private List<View> pointViewList = new ArrayList<View>(); public EmojiAdapter(Context context, EditText editText, ViewPager mEmojiViewPager, LinearLayout linearLayout) { this.mContext = context; this.mMessageEditText = editText; this.mEmojiViewPager = mEmojiViewPager; this.mPointContain = linearLayout; initEmoji(); computeGridView(); initPoint(); mEmojiViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { for (int i = 0; i < pointViewList.size(); i++) { if (position == i) { pointViewList.get(i).setBackgroundResource(R.drawable.point_select); } else { pointViewList.get(i).setBackgroundResource(R.drawable.point); } } } @Override public void onPageScrollStateChanged(int state) { } }); } /** * 初始化小点 */ private void initPoint() { for (int i = 0; i < totalPage; i++) { View view = new View(mContext); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); params.rightMargin = dp2px(8); params.width = dp2px(10); params.height = dp2px(10); if (i == 0) { view.setBackgroundResource(R.drawable.point_select); } else { view.setBackgroundResource(R.drawable.point); } view.setLayoutParams(params); mPointContain.addView(view); pointViewList.add(view); } } //初始化表情 private void initEmoji() { for (int i = 1; i <= 117; i++) { String drawableName; if (i < 10) { drawableName = "emoji_0" + i; } else { drawableName = "emoji_" + i; } int drawableId = getDrawableId(drawableName); mSparseArray.put(drawableId, drawableName); emojiList.add(drawableId); } } private void computeGridView() { totalPage = (int) (emojiList.size() / 20f + 0.5f);//计算装表情的总的页数 Log.e("399", "totalPage " + totalPage); for (int i = 0; i < totalPage; i++) { GridView gridView = (GridView) View.inflate(mContext, R.layout.gridview, null); int currentPage = i; gridView.setAdapter(new EmojiGridViewAdapter(currentPage)); mGridViewList.add(gridView); } } @Override public int getCount() { if (mGridViewList != null && mGridViewList.size() > 0) { return mGridViewList.size(); } return 0; } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public Object instantiateItem(ViewGroup container, int position) { container.addView(mGridViewList.get(position)); return mGridViewList.get(position); } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView(mGridViewList.get(position)); } private int getDrawableId(String drawableName) { return mContext.getResources().getIdentifier(drawableName, "drawable", mContext.getPackageName()); } /** * 表情适配器 */ class EmojiGridViewAdapter extends BaseAdapter { int currentPage = 0; public EmojiGridViewAdapter(int currentPage) { this.currentPage = currentPage; } @Override public int getCount() { if (currentPage == totalPage - 1) {//最后一页 return emojiList.size() - (totalPage - 1) * 20 + 1;//加上最后一个删除表情 } return 21; } @Override public Object getItem(int i) { return emojiList.get(i); } @Override public long getItemId(int i) { return i; } @Override public View getView(int i, View view, ViewGroup viewGroup) { ViewHolder holder; if (view == null) { holder = new ViewHolder(); view = View.inflate(mContext, R.layout.item_emoji, null); holder.mEmj = (ImageView) view.findViewById(R.id.iv_emj); view.setTag(holder); } else { holder = (ViewHolder) view.getTag(); } i = currentPage * 20 + i;//表情的索引 final int j = i; ImageView mEmjImageView = holder.mEmj; int delPos = 20 * currentPage + 20;//每页的最后一个的位置 if (i == delPos || i == 117) {//如果位置是每一页的最后一个或者最后一页的最后一个表情的话就插入删除表情 mEmjImageView.setImageResource(R.drawable.face_del_ico_dafeult); } else { mEmjImageView.setImageResource(emojiList.get(i)); } mEmjImageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (20 * currentPage + 20 == j || j == 117) {//点击的是删除表情 doDelete(); } else { String enojiName = mSparseArray.get(emojiList.get(j)); // mMessageEditText.setText(enojiName); enojiName = "[" + enojiName + "]";// [emoji_01] //将表情包使用SpannableStringBuilder包装,并显示到EditText中 putEmojiToEditText(enojiName, j); } } }); return view; } } /** * 删除表情或者文字 */ private void doDelete() { Log.e("399", "删除"); int selectionStart = mMessageEditText.getSelectionStart();// 获取光标的位置 if (selectionStart > 0) { String body = mMessageEditText.getText().toString(); if (!TextUtils.isEmpty(body)) { String tempStr = body.substring(0, selectionStart); String lastString = tempStr.substring(selectionStart - 1);//获取最后一个字符串 if("]".equals(lastString)) {//判断最后一个字符串是不是"]" int i = tempStr.lastIndexOf("[");// 获取最后一个表情的位置 if (i != -1) { CharSequence cs = tempStr .subSequence(i, selectionStart); if (cs.toString().contains("[emoji_")) {// 判断是否是一个表情 mMessageEditText.getEditableText().delete(i, selectionStart); return; } } }else { mMessageEditText.getEditableText().delete(tempStr.length() - 1, selectionStart); } } } } private void putEmojiToEditText(String enojiName, int j) { SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(enojiName); //获取表情的drawable Drawable drawable = mContext.getResources().getDrawable(emojiList.get(j)); //屏幕适配,这种宽高为35dp int size = (int) (35 * mContext.getResources().getDisplayMetrics().density); drawable.setBounds(0, 0, size, size); //将图片使用ImageSpan包装起来 ImageSpan imageSpan = new ImageSpan(drawable); spannableStringBuilder.setSpan(imageSpan, 0, enojiName.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); Editable editable = mMessageEditText.getText(); int selectionEnd = mMessageEditText.getSelectionEnd(); if (selectionEnd < editable.length()) { editable.insert(selectionEnd, spannableStringBuilder); } else { editable.append(spannableStringBuilder); } } static class ViewHolder { ImageView mEmj; } private int dp2px(int dp) { return (int) (dp * mContext.getResources().getDisplayMetrics().density); } }
实现EditText显示图片的核心代码如下:
String enojiName = mSparseArray.get(emojiList.get(j)); // mMessageEditText.setText(enojiName); enojiName = "[" + enojiName + "]";// [emoji_01] //将表情包使用SpannableStringBuilder包装,并显示到EditText中
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(enojiName); //获取表情的drawable Drawable drawable = mContext.getResources().getDrawable(emojiList.get(j)); //屏幕适配,这种宽高为35dp int size = (int) (35 * mContext.getResources().getDisplayMetrics().density); drawable.setBounds(0, 0, size, size); //将图片使用ImageSpan包装起来 ImageSpan imageSpan = new ImageSpan(drawable); spannableStringBuilder.setSpan(imageSpan, 0, enojiName.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); Editable editable = mMessageEditText.getText(); int selectionEnd = mMessageEditText.getSelectionEnd(); if (selectionEnd < editable.length()) { editable.insert(selectionEnd, spannableStringBuilder); } else { editable.append(spannableStringBuilder); }
实现listView里显示图片表情的核心代码如下:
private void parseMessage(String s, TextView mMessageTextView) { SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(s); Pattern pattern = Pattern.compile("\\[(\\S+?)\\]");//匹配[xx]的字符串 Matcher matcher = pattern.matcher(s); while (matcher.find()) { int start = matcher.start(); int end = matcher.end(); String group = matcher.group(); group = group.substring(1, group.length() - 1); Log.e("399", group); int drawableId = getResources().getIdentifier(group, "drawable", getPackageName()); Drawable drawable = getResources().getDrawable(drawableId); int size = (int) (35 * getResources().getDisplayMetrics().density); drawable.setBounds(0, 0, size, size); ImageSpan imageSpan = new ImageSpan(drawable); spannableStringBuilder.setSpan(imageSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } mMessageTextView.setText(spannableStringBuilder, TextView.BufferType.SPANNABLE); }