Android开发笔记之发送小表情的实现

本博客主要实现的是像QQ表情的发送以及文字与表情的一起发送


我们首先要明白QQ表情的发送其实是一种特别的文本,也是文本的形式,所以我们需要将QQ表情转化为特殊的文本形式
第一步我们先做一个资源工具类,如下所示

//我们把表情资源做成一个工具类
public class EmoUtils {
    public static int[] face = new int[] { R.drawable.ee_1, R.drawable.ee_2,
            R.drawable.ee_3, R.drawable.ee_4, R.drawable.ee_5, R.drawable.ee_6,
            R.drawable.ee_7, R.drawable.ee_8, R.drawable.ee_9,
            R.drawable.ee_10, R.drawable.ee_11, R.drawable.ee_12,
            R.drawable.ee_13, R.drawable.ee_14, R.drawable.ee_15,
            R.drawable.ee_16, R.drawable.ee_17, R.drawable.ee_18,
            R.drawable.ee_19, R.drawable.ee_20, R.drawable.ee_21,
            R.drawable.ee_22, R.drawable.ee_23, R.drawable.ee_24,
            R.drawable.ee_25, R.drawable.ee_26, R.drawable.ee_27,
            R.drawable.ee_28, R.drawable.ee_29, R.drawable.ee_30,
            R.drawable.ee_31, R.drawable.ee_32, R.drawable.ee_33,
            R.drawable.ee_34, R.drawable.ee_35, };
    public static String[] face_name = new String[] { "ee_1", "ee_2", "ee_3",
            "ee_4", "ee_5", "ee_6", "ee_7", "ee_8", "ee_9", "ee_10", "ee_11",
            "ee_12", "ee_13", "ee_14", "ee_15", "ee_16", "ee_17", "ee_18",
            "ee_19", "ee_20", "ee_21", "ee_22", "ee_23", "ee_24", "ee_25",
            "ee_26", "ee_27", "ee_28", "ee_29", "ee_30", "ee_31", "ee_32",
            "ee_33", "ee_34", "ee_35" };

}

第二步我们做一个ImageUtils用来转化表情,具体的代码如下

//在这里对三个参数解释一下,
//第一个参数为上下文
//第二参数为资源的名字,也就是图片的真实名称
    public static SpannableString getSpanableString(Context context, String name)
            throws Exception {
            //html图片的标识符
        String html = "<img src='" + name + "'/>";
//此出得到的是一个field文件,也就是根据名字找到的资源Id文件      
Field field =R.drawable.class.getDeclaredField(name);
//但是我们拿到的资源是一个string字符串,需要包装称为一个资源ID
        int resourceId = Integer.parseInt(field.get(null).toString());
        //通过bitmapFactory工厂处理解码,装化成bitmap图片
        Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),
                resourceId);
    //要让图片替代指定的文字就要用ImageSpan
     ImageSpan imageSpan = new ImageSpan(context, bitmap);
        //此处是将html标识符转化为特殊文本,SpannnableString类就是这么一个
SpannableString spannableString = new    不      SpannableString(html);//html就是图片的前缀名
spannableString.setSpan(imageSpan, 0,html.length(),Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        return spannableString;
    }
  1. 由于R.drawable中的资源ID都是public的静态变量,因此,可直接使用Field.get方法获得这些变量的值。如果是private或protected的变量,需要field.setAccessible(true)设置变量值的访问权限才可以读写这些变量。
  2. 使用Field.get方法获得变量值时,如果是静态变量。Field.get方法的参数值设为null即可。如果不是静态变量,需要为Field.get方法指定一个变量所在类的对象作为参数值。
  3. 由于EditText类不能直接插入Span对象,因此,需要先使用SpannableString对象来封装Span对象(如本例中的ImageSpan对象),再将SpannableString对象插入到EditText控件中
  4. .html.length()此处一定要填入的html的长度,因为每个表情的名字长度是不一样的,例如1-9的表情名字为ee_9,后面的名字为ee_10这样的话,每次去截取的长度是不一样的,如果填入的是固定长度的话,比如4,前面9个没事情,后面的点击就会卡死,因为它拿着4去截取长度名字,占不到自己要加载的资源名字,所以会造成ANR

通过

    // 利用反射机制,通过资源名字得到资源的ID
    public static int getResourceId(String resName) {
        try {
            Field field = R.drawable.class.getField(resName);
            return Integer.parseInt(field.get(null).toString());
        } catch (Exception e) {
            e.printStackTrace();
            Log.i("TAG", "faild to get resource ID !");
        }
        return 0;
    }

通过这一步最后将我们要显示的图片显示在textView上面

    /**
     * 通过图片的名字,显示图片,主要用在TextView中
     * 
     * @param context
     * @param htmlString 图片的名字
     * @return 可显示的图片的String类型
     */
    public static CharSequence formatString(final Context context,
            String htmlString) {
        CharSequence ch = Html.fromHtml(htmlString, new Html.ImageGetter() {

            @TargetApi(Build.VERSION_CODES.LOLLIPOP)
            @Override
            public Drawable getDrawable(String source) {
Drawable drawable = context.getResources().getDrawable(
getResourceId(source));
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
0drawable.getIntrinsicHeight());
                return drawable;
            }
        }, null);

        return ch;
    }

基本处理过程就是这样,
小表情的布局我们用gridview来实现
在gridview的Item点击事件监听的时候,editText获得输入内容通过如下这句代码实现,记得要try-catch

et.append(ImageUtils.getSpanableString(MainActivity.this, EmoUtils.face_name[position]));

控件上面内容的显示即textView内容的显示
我们通过工具类中的formatString方法将表情显示上去
此处传入两个参数
1.上下文 context
2.editText获得到的内容et.getText().toString()

tv.setText(ImageUtils.formatString(MainActivity.this, et.getText().toString()));

最后就是我们adapter的书写,代码如下

public class GridAdapter extends BaseAdapter {

    int[] face;
    Context context;

    public GridAdapter(Context context, int[] face) {
        // TODO Auto-generated constructor stub
        this.context = context;
        this.face = face;
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return face.length;
    }

    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub

        View v = View.inflate(context, R.layout.item, null);
        ImageView im = (ImageView) v.findViewById(R.id.imageView1);
        im.setImageResource(face[position]);
        return v;
    }
}

小表情资源大家自己找下,找不到的话,直接下载QQ解压出来,去一个res文件下面找到
还有什么不懂的,可以1215167396call我

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值