实现RichEdit(二)---实现服务器通信

前言:上一篇,我们说了如何实现了RichEdit,但现实中总会将消息发送到服务器保存起来,众所周知,服务器数据库是不可能保存图片的,所以我们要把图片转换成对应的字符保存在服务器,然后客户端在下载到服务器传来的字符以后,将对应的字符转换成图片,下面我讲讲在本地如何实现这个功能,只要这个懂了以后,对于服务器通信的东东难度不大,我就不再另写DEMO了;

例图:

实现功能:在EditText中输入表情和文字,在点击“显示在下面的TextView中”后,将EditText中的内容转换为文本,在下面的TextView中将此文本解析,显示出对应的图片;

 

这个例子是在上篇例子的基础上修改而来的,我这里只对修改的两个地方做下阐述:

一、点击表情GRIDVIEW中的某一项的监听器----gridViewFaceItemClickListener

/**
 * 点击表情GRIDVIEW中的某一项的监听器
 */
private OnItemClickListener gridViewFaceItemClickListener = new AdapterView.OnItemClickListener() {

	@Override
	public void onItemClick(AdapterView<?> arg0, View view, int position,
			long id) {
		// TODO Auto-generated method stub
		// 首先得到当前用户点击的表情的信息
		Smile smile = smiles.get(position);
		// 得到当前CURSOR位置
		int cursor = ET_content.getSelectionStart();
		Field f;
		try {
			// 根据资源名字得到Resource和对应的Drawable
			f = (Field) R.drawable.class.getDeclaredField(smile.getName());
			int j = f.getInt(R.drawable.class);
			Drawable d = getResources().getDrawable(j);
			d.setBounds(0, 0, 35, 35);// 设置表情图片的显示大小

			// 显示在EditText中
			String str = null;
			int pos = position + 1;
			if (pos < 10) {
				str = "f00" + pos;
			} else if (pos < 100) {
				str = "f0" + pos;
			} else {
				str = "f" + pos;
			}
			SpannableString ss = new SpannableString(str);
			ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BOTTOM);
			ss.setSpan(span, 0, str.length(),
					Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
			ET_content.getText().insert(cursor, ss);

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

};
注意这里的修改位置:

String str = null;
int pos = position + 1;
if (pos < 10) {
	str = "f00" + pos;
} else if (pos < 100) {
	str = "f0" + pos;
} else {
	str = "f" + pos;
}
SpannableString ss = new SpannableString(str);
在上一篇中,我们在实例话String str="img";而这里实例化为了对应的表情图片的名字;这么做有什么用么;这就是SpannableString功能了,当我们用EditText.getText().toString()显示EditText中的字符时,那么对于图片是没有办法显示的,那怎么办,总不能不显示什么东东来替代图片的位置吧,而这里的传进SpannableString的str就是当调用EditText.getText().toString()时替代所要显示的图片的;

二、然后是OnCreate()函数里

protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);

	// 和 各个组件变量初始化
	InitVariable();
	// 初始化GridView,将其与Adapter绑定
	InitGridView();
	
	//表情显示图片点击监听
	IV_face.setOnClickListener(faceClickListener);
	
	//监听点击了表情的哪一项
	GV_faceView.setOnItemClickListener(gridViewFaceItemClickListener);
	
	//EditText点击监听
	ET_content.setOnClickListener(EditContentClickListener);
	
	
	Button btn=(Button)findViewById(R.id.getText);
	final TextView tv=(TextView)findViewById(R.id.text);
	btn.setOnClickListener(new OnClickListener() {
		
		@Override
		public void onClick(View v) {
			// TODO Auto-generated method stub
			String str=ET_content.getText().toString();
			String zhengze = "f0[0-9]{2}|f10[0-7]"; // 正则表达式,用来判断消息内是否有表情
			SpannableString spannableString = ExpressionUtil
					.getExpressionString(getApplicationContext(),str, zhengze);
			
			tv.setText(spannableString);
		}
	});	
}
在OnCreate()函数里,增加了几句话,如下:

Button btn=(Button)findViewById(R.id.getText);
final TextView tv=(TextView)findViewById(R.id.text);
btn.setOnClickListener(new OnClickListener() {
	
	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		String str=ET_content.getText().toString();
		String zhengze = "f0[0-9]{2}|f10[0-7]"; // 正则表达式,用来判断消息内是否有表情
		SpannableString spannableString = ExpressionUtil
				.getExpressionString(getApplicationContext(),str, zhengze);
		
		tv.setText(spannableString);
	}
});	
这就是对“显示在下面TextView中”按钮的实例化和监听函数,这里最重要的是onClick()里的几句话:

第一句:String str=ET_content.getText().toString(); 获得当前EditText中的字符;
第二句:String zhengze = "f0[0-9]{2}|f10[0-7]";  是一个正则表达式,用来判断消息内是否有表情
第三句:SpannableString spannableString = ExpressionUtil.getExpressionString(getApplicationContext(),str, zhengze);这句是一个函数,正是我们下面要讲的,这句的功能是将传进去的字符,经过正则表达式匹配,找到对应字符的图片,最后返回SpannableString对象的实例;
第四句:tv.setText(spannableString);将返回的图文混排的文字设置到TextView中;

下面我们看看getExpressionString()函数

三、字符解析类----ExpressionUtil

这个类里总共有两个函数,其实主要就一个,另一个只是在内部被调用的,先看看上面被调用到的getExpressionString()函数

/**
 * 得到一个SpanableString对象,通过传入的字符串,并进行正则判断
 * @param context
 * @param str
 * @return
 */
public static SpannableString getExpressionString(Context context,String str,String zhengze){
	SpannableString spannableString = new SpannableString(str);
    Pattern sinaPatten = Pattern.compile(zhengze, Pattern.CASE_INSENSITIVE);		//通过传入的正则表达式来生成一个pattern
    try {
        dealExpression(context,spannableString, sinaPatten, 0);
    } catch (Exception e) {
        Log.e("dealExpression", e.getMessage());
    }
    return spannableString;
}
这个没什么实际功能,就是将传进来的字符和正则表达式进行封装,传到dealExpression()这个函数里面去,我们看看这个函数是什么功能;

/**
 * 对spanableString进行正则判断,如果符合要求,则以表情图片代替
 * @param context
 * @param spannableString
 * @param patten
 * @param start
 * @throws SecurityException
 * @throws NoSuchFieldException
 * @throws NumberFormatException
 * @throws IllegalArgumentException
 * @throws IllegalAccessException
 */
public static void dealExpression(Context context,SpannableString spannableString, Pattern patten, int start) throws Exception {
	Matcher matcher = patten.matcher(spannableString);
    while (matcher.find()) {
        String key = matcher.group();//得到整个匹配,也就是文件名,比如f001
        if (matcher.start() < start) {
            continue;
        }
        Field field = R.drawable.class.getDeclaredField(key); //根据得到的名字获得资源
		int resId = Integer.parseInt(field.get(null).toString());		//通过上面匹配得到的字符串来生成图片资源id
        if (resId != 0) {
            Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resId);	
            ImageSpan imageSpan = new ImageSpan(bitmap);				//通过图片资源id来得到bitmap,用一个ImageSpan来包装
            int end = matcher.start() + key.length();					//计算该图片名字的长度,也就是要替换的字符串的长度
            spannableString.setSpan(imageSpan, matcher.start(), end, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);	//将该图片替换字符串中规定的位置中
            if (end < spannableString.length()) {						//如果整个字符串还未验证完,则继续。。
                dealExpression(context,spannableString,  patten, end);
            }
            break;
        }
    }
}
1、首先将字符与正则表达式匹配:Matcher matcher = patten.matcher(spannableString);
2、对于匹配的结果: String key = matcher.group();得到整个匹配,因为我们定义的正则表达式只是匹配的文件句,匹配的结果肯定也就是文件名比如:f001;
3、下面的几句就是根据文件名,得图片资源然后放到spannableString中,替代这个文件名

参考文章:《完整实例实现QQ表情的发送和接收》:http://blog.csdn.net/duancanmeng/article/details/7677144

源码内容:在源码中除了我上面讲的例子的源码外,还有我参考的这篇博客的源码;向博主致敬!因为您让我们这些初接触者少走了弯路,谢谢!

源码地址:http://download.csdn.net/detail/harvic880925/6842393

请大家尊重原创者版权,转载请标明出处:http://blog.csdn.net/harvic880925/article/details/18216491 谢谢!


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值