Android - Emoji表情图文混排

         最近在一个项目中做即时通讯,涉及到emoji表情的发送。为了使iphone和Android表情一致,就不能单纯的使用emoji表情编码的方式。最后决定使用图片的方式,使用
SpannableString进行图文混排。下面是开发过程中的一个demo。
一、效果图

二、图片资源准备

三、布局文件只是一个简单的TextView
  <TextView
    android:id="@+id/txt_content"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:textColor="#000000"
    />

四、MainActivity
import android.app.Activity;
import android.os.Bundle;
import android.text.SpannableString;
import android.widget.TextView;

import java.util.HashMap;
import java.util.Map;

public class MainActivity extends Activity {

  private TextView txt_content;

  private String testString = "[微笑]早上好,[撇嘴][色][发呆]晚上好";
  private Map<String, String> fachMap = new HashMap<String, String>();

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initView();
    initData();
  }


  private void initView() {
    txt_content = (TextView)findViewById(R.id.txt_content);
  }

  private void initData(){
    SpannableString txt = FaceUtil.getExpressionString(this,testString);
    txt_content.setText(txt);
  }

}

五、FaceUtil.java图文混排的核心类,包含正则表达式判断表情,以及转化为SpannableString的核心方法。
public class FaceUtil {
  private static Map<String, String> faceMap = new HashMap<String, String>();

  static {
    faceMap.put("[微笑]", "expression_1");
    faceMap.put("[撇嘴]", "expression_2");
    faceMap.put("[色]", "expression_3");
    faceMap.put("[发呆]", "expression_4");
    faceMap.put("[得意]", "expression_5");
    faceMap.put("[流泪]", "expression_6");
    faceMap.put("[害羞]", "expression_7");
    faceMap.put("[闭嘴]", "expression_8");
  }

  public static SpannableString getExpressionString(Context context, String text) {

    String rgFace = "\\[[^\\]]+\\]";
    Pattern ptFace = Pattern.compile(rgFace, Pattern.CASE_INSENSITIVE);
    return dealExpression(context, text, ptFace, 0);
  }

  private static SpannableString dealExpression(Context context,
                                         String text, Pattern patten, int start) {
    SpannableString spannableString = new SpannableString(text);
    Matcher matcher = patten.matcher(spannableString);
    while (matcher.find()) {
      Log.e("FaceUtil","mact");
      String key = matcher.group();
      if (matcher.start() < start) {
        continue;
      }
      String value = faceMap.get(key);
      Log.e("FaceUtil","mact"+value);
      if (TextUtils.isEmpty(value)) {
        continue;
      }
      int resId = context.getResources().getIdentifier(value, "drawable",
        context.getPackageName());
      Log.e("FaceUtil","mact"+resId);
      // 通过上面匹配得到的字符串来生成图片资源id
      if (resId != 0) {
        Drawable drawable = context.getResources().getDrawable(resId);
        drawable.setBounds(0, 0, DensityUtil.dip2px(context, 26), DensityUtil.dip2px(context, 26));
        // 通过图片资源id来得到bitmap,用一个ImageSpan来包装
        ImageSpan imageSpan = new ImageSpan(drawable, ImageSpan.ALIGN_BOTTOM);
        // 计算该图片名字的长度,也就是要替换的字符串的长度
        int end = matcher.start() + key.length();
        // 将该图片替换字符串中规定的位置中
        spannableString.setSpan(imageSpan, matcher.start(), end,
          Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
      }
    }
    return spannableString;
  }

}

六、一个dp与px互相转化的工具类
public class DensityUtil {
    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     */
    public static int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    /**
     * 根据手机的分辨率从 px(像素) 的单位 转成为 dp
     */
    public static int px2dip(Context context, float pxValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }
}

附:全套的emoji表情资源 http://download.csdn.net/detail/lo_ser/9708414

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值