您的位置:首页 > 移动开发 > Android开发

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

2016-07-20 15:59 459 查看
本博客主要实现的是像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;
}


由于R.drawable中的资源ID都是public的静态变量,因此,可直接使用Field.get方法获得这些变量的值。如果是private或protected的变量,需要field.setAccessible(true)设置变量值的访问权限才可以读写这些变量。

使用Field.get方法获得变量值时,如果是静态变量。Field.get方法的参数值设为null即可。如果不是静态变量,需要为Field.get方法指定一个变量所在类的对象作为参数值。

由于EditText类不能直接插入Span对象,因此,需要先使用SpannableString对象来封装Span对象(如本例中的ImageSpan对象),再将SpannableString对象插入到EditText控件中

.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我
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: