EditText显示表情

本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);
}


demo的下载地址http://download.csdn.net/detail/cool_fuwei/9590103

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现EditText限制长度为10,同时允许输入Emoji表情包,并且避免表情包出现乱码,可以使用自定义的InputFilter来实现。具体步骤如下: 1. 定义一个EmojiInputFilter类,继承InputFilter接口。 2. 在EmojiInputFilter中实现filter()方法,实现限制长度和过滤Emoji表情包的逻辑,具体实现如下: ``` public class EmojiInputFilter implements InputFilter { private static final int MAX_LENGTH = 10; @Override public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { int keep = MAX_LENGTH - (dest.length() - (dend - dstart)); if (keep <= 0) { return ""; } else if (keep >= end - start) { // 如果输入的字符数小于等于限制的长度,则不需要过滤表情包 return null; } else { // 如果输入的字符数大于限制的长度,则需要过滤表情包 int k = start; int len = 0; StringBuilder sb = new StringBuilder(); for (; k < end; k++) { int codePoint = source.charAt(k); if (!Character.isHighSurrogate(codePoint) && !Character.isLowSurrogate(codePoint) && len < keep) { len++; sb.append(Character.toChars(codePoint)); } else { break; } } return sb.toString(); } } } ``` 3. 在EditText中设置输入类型为文本类型,同时添加自定义的EmojiInputFilter,实现限制长度和过滤Emoji表情包的逻辑,具体代码如下: ``` // 设置EditText的输入类型为文本类型 editText.setInputType(InputType.TYPE_CLASS_TEXT); // 添加自定义的EmojiInputFilter,实现限制长度和过滤Emoji表情包的逻辑 editText.setFilters(new InputFilter[] {new EmojiInputFilter()}); ``` 4. 在显示输入框中的内容时,通过EmojiCompat工具类将Unicode编码转换成对应的Emoji表情,具体代码如下: ``` // 初始化EmojiCompat EmojiCompat.Config config = new BundledEmojiCompatConfig(context); EmojiCompat.init(config); // 在显示输入框中的内容时,将Unicode编码转换成对应的Emoji表情 CharSequence processed = EmojiCompat.get().process(text); textView.setText(processed); ``` 这样就可以实现EditText限制长度为10,同时允许输入Emoji表情包,并且避免表情包出现乱码了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值