Android最完整的仿QQ表情聊天图文展示代码示例

安卓最完整的表情聊天特效(大家可以看我上一篇文章websocket的整合,这是他的后续)

首先我们需要知道安卓输入的是EditText 显示的内容是TextView, 但是TextView里面又只能显示文字,那怎么能够同时图文展示呢? 接下来带领你们展示是怎么实现的。

既然需要展示表情,所以表情的图片包还是需要大家去网上收集的在这里就不和大家详说了。当我们从网上下载图片后如下图这样放在assets文件夹里面,当前你也可以在里面在建一个自己喜欢的目录

在这里插入图片描述

然后我们需要全局首次加载这个图片,使用集合存储起来

public class ApplicationContext extends Application implements Thread.UncaughtExceptionHandler {
    @Override
    public void onCreate() {
        super.onCreate();
        x.Ext.init(this);
        x.Ext.setDebug(false);
        Thread.setDefaultUncaughtExceptionHandler(this);
        initBiaoqingMap();
    }
    @Override
    public void uncaughtException(@NonNull Thread t, @NonNull Throwable e) {
        System.exit(0);
    }
    public String getStringFromId(int stringId){
        return getResources().getString(stringId);
    }
    private void initBiaoqingMap() {
        biaoqingMap.put("[微笑]", "wechat_emotion_0.png");
        biaoqingMap.put("[撇嘴]", "wechat_emotion_1.png");
        biaoqingMap.put("[色]", "wechat_emotion_2.png");
        biaoqingMap.put("[发呆]", "wechat_emotion_3.png");
        biaoqingMap.put("[得意]", "wechat_emotion_4.png");
        biaoqingMap.put("[流泪]", "wechat_emotion_5.png");
        biaoqingMap.put("[害羞]", "wechat_emotion_6.png");
        biaoqingMap.put("[闭嘴]", "wechat_emotion_7.png");
        biaoqingMap.put("[睡]", "wechat_emotion_8.png");
        biaoqingMap.put("[大哭]", "wechat_emotion_9.png");
        biaoqingMap.put("[尴尬]", "wechat_emotion_10.png");
        biaoqingMap.put("[发怒]", "wechat_emotion_11.png");
        biaoqingMap.put("[调皮]", "wechat_emotion_12.png");
        biaoqingMap.put("[呲牙]", "wechat_emotion_13.png");
        biaoqingMap.put("[惊讶]", "wechat_emotion_14.png");
        biaoqingMap.put("[难过]", "wechat_emotion_15.png");
    }
}

然后再聊天界面首次用到的时候加载

   @ViewInject(R.id.chat_biaoqing_GridView)
    private GridView chat_biaoqing_GridView;
    private BiaoqingAdapter biaoqingAdapter;
    private String[] wechatemojis;
    private void initBaioqing(){
        try {
            wechatemojis = getResources().getAssets().list(Common.biaoqing_path);
            biaoqingAdapter = new BiaoqingAdapter(wechatemojis, getBaseActivityContext());
            chat_biaoqing_GridView.setAdapter(biaoqingAdapter);
            chat_biaoqing_GridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    String fileName = wechatemojis[position];
                    String mapKey = getBiaoqingkeyFromValue(fileName);
                    chat_input.append(mapKey);
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

这样有啥用呢, 这样我们就可以用文字和图片关联起来, 并且还能再Textview中显示了,通过自定义控件特殊字符串转图片的形式实现图文展示,控件代码如下:

@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(biaoqing_path + "/" + value);
                        bit= BitmapFactory.decodeStream(bitmap);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    Drawable drawable = new BitmapDrawable(bit);
                    try {
                        if (drawable != null) {
                            drawable.setBounds(0, 0, 65, 65);
                            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();
        }
    }
}

使用这个控件的时候需要set数据后再initView()一下,然后本地上就差不多了, 但是我调试出现一下很大的bug, 就是文字和图片没对齐, 原因可能是图片的大小的文字不匹配这时我们就应该这样操作把文字和图片横向对齐

public class VerticalImageSpan extends ImageSpan {
    public VerticalImageSpan(Drawable drawable) {
        super(drawable);
    }
    @Override
    public 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;
    }
    @Override
    public 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();
    }
}

终于再我历经一整天的努力下完成了,下面是我运行示例截图,分享下, 这很简单的, 网上很多。代码就不分享了

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值