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

来源:互联网 发布:21天学通java这书怎样 编辑:程序博客网 时间:2024/04/28 17:59

本博客主要实现的是像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 0