博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
实现RichEdit(二)---实现服务器通信
阅读量:2021 次
发布时间:2019-04-28

本文共 6239 字,大约阅读时间需要 20 分钟。

前言:上一篇,我们说了如何实现了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表情的发送和接收》:

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

源码地址:

请大家尊重原创者版权,转载请标明出处: 谢谢!

你可能感兴趣的文章
Flask(4)- flask请求上下文源码解读、http聊天室单聊/群聊(基于gevent-websocket)...
查看>>
Flask(3)- flask中的CBV、werkzeug+上下文初步解读、偏函数和线程安全
查看>>
Flask(5)- Flask-Session组件、WTForms组件、数据库连接池(POOL)
查看>>
Git的使用(1)
查看>>
MongoDB
查看>>
人工智能
查看>>
微信公众号之订阅号开发 - 智能机器人对话(仅限文本类型)
查看>>
H5开发APP入门
查看>>
SQLAlchemy
查看>>
Websocket - Websocket原理(握手、解密、加密)、基于Python实现简单示例
查看>>
阿里云部署 Flask + uWSGI + Nginx
查看>>
Pycharm配置同步服务器
查看>>
ansible(1)
查看>>
Flask蓝图目录、Flask-SQLAlchemy、Flask-Script、Flask-Migrate
查看>>
爬虫(1)
查看>>
Celery(一个懂得 异步任务、定时任务、周期任务 的"芹菜")
查看>>
ansible(3)
查看>>
爬虫(3)
查看>>
爬虫(2)
查看>>
Scrapy框架(3)
查看>>