Android编写简单的聊天室应用

最近写了一个简单的聊天室应用,可以发送表情,更改头像这些功能。主要技术点就是怎样把表情图片放到textview等Ui控件中展示。这里废话不多说,下面是效果图:

这里主要讲下怎样把文本替换到表情,先说下思路,首先我们的图片是保存在本地资源目录drawable中而所有的资源文件都是R这个类来管理,所以我们可以利用正则表达式找出图片id包装成ImageSpan然后把ImageSpan放到SpannableString中,最后把SpannableString放入edittext中,下面是源码:

package com.coreandroid.util; import java.lang.reflect.Field; import java.util.regex.Matcher; import java.util.regex.Pattern; import android.content.Context; import android.text.Spannable; import android.text.SpannableString; import android.text.style.ImageSpan; import android.util.Log; import com.coreandroid.chart.R; public class ExpressionUtil { /** * 对spanableString进行正则判断,如果符合要求,则以表情图片代替 * * @param context * @param spannableString * @param patten * @param start */ public static void matchExpression(Context context, SpannableString spannableString, Pattern patten, int start) throws Exception { Matcher matcher = patten.matcher(spannableString); while (matcher.find()) { String key = matcher.group(); if (matcher.start() < start) { continue; } Field field = R.drawable.class.getDeclaredField(key); int resId = field.getInt(null); // 通过上面匹配得到的字符串来生成图片资源id if (resId != 0) { ImageSpan imageSpan = new ImageSpan(context, resId); // 通过图片资源id来得到bitmap,用一个ImageSpan来包装 int end = matcher.start() + key.length(); // 计算该图片名字的长度,也就是要替换的字符串的长度 spannableString.setSpan(imageSpan, matcher.start(), end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); // 将该图片替换字符串中规定的位置中 if (end < spannableString.length()) { // 如果整个字符串还未验证完,则继续。。 matchExpression(context, spannableString, patten, end); } break; } } } /** * 得到一个SpanableString对象,通过传入的字符串,并进行正则判断 * * @param context * @param str * @return SpannableString */ public static SpannableString getExpressionString(Context context, String str, String zhengze) { SpannableString spannableString = new SpannableString(str); Pattern sinaPatten = Pattern.compile(zhengze); // 通过传入的正则表达式来生成一个pattern try { matchExpression(context, spannableString, sinaPatten, 0); } catch (Exception e) { Log.e("dealExpression", e.getMessage()); } return spannableString; } }

下面是聊天记录列表的adapter,这里主要是动态的改变每个Item的布局来区分是自己还是他人的发言,具体源码如下:

package com.coreandroid.adapter; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import android.content.Context; import android.text.SpannableString; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; import com.coreandroid.chart.R; import com.coreandroid.entity.MessageInfo; import com.coreandroid.util.CommonUtils; import com.coreandroid.util.ExpressionUtil; public class ChartListAdapter extends BaseAdapter { private Context context; private LayoutInflater inflater; private List<MessageInfo> data; private DateFormat df; public ChartListAdapter(Context context, List<MessageInfo> data) { super(); this.context = context; inflater = LayoutInflater.from(context); this.data = data; df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); } @Override public int getCount() { return data.size(); } @Override public Object getItem(int position) { return data.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { convertView = inflater.inflate(R.layout.chart_list_item, null); holder = new ViewHolder(convertView); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.setData((MessageInfo) getItem(position)); return convertView; } private class ViewHolder { private ImageView image; private TextView text; private TextView title; private RelativeLayout rl; public ViewHolder(View convertView) { image = (ImageView) convertView .findViewById(R.id.chart_list_item_headicon); text = (TextView) convertView .findViewById(R.id.chart_list_item_message); title = (TextView) convertView .findViewById(R.id.chart_list_item_title); rl = (RelativeLayout) convertView .findViewById(R.id.rl_chart_list_bottom); } public void setData(MessageInfo msg) { RelativeLayout.LayoutParams rl_tv_msg_left = (RelativeLayout.LayoutParams) text .getLayoutParams(); RelativeLayout.LayoutParams rl_iv_headicon_left = (RelativeLayout.LayoutParams) image .getLayoutParams(); RelativeLayout.LayoutParams rl_tv_title = (RelativeLayout.LayoutParams) title .getLayoutParams(); RelativeLayout.LayoutParams rl_buttom = (RelativeLayout.LayoutParams) rl .getLayoutParams(); if (!CommonUtils.getDeviceId().equalsIgnoreCase(msg.getUsermac())) { // 根据本地的mac地址来判断该条信息是属于本人所说还是对方所说 // 如果是自己说的,则显示在右边;如果是对方所说,则显示在左边 rl_buttom.addRule(RelativeLayout.ALIGN_PARENT_TOP); rl_tv_title.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); rl_tv_title.addRule(RelativeLayout.ALIGN_PARENT_LEFT); rl_tv_title.addRule(RelativeLayout.BELOW, R.id.rl_chart_list_bottom); rl_iv_headicon_left.addRule(RelativeLayout.ALIGN_PARENT_LEFT); rl_iv_headicon_left.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); rl_tv_msg_left.addRule(RelativeLayout.RIGHT_OF, R.id.chart_list_item_headicon); text.setBackgroundResource(R.drawable.incoming); String titleStr = msg.getUsermac() + "-" + df.format(new Date()); title.setText(titleStr); } else { rl_buttom.addRule(RelativeLayout.ALIGN_PARENT_TOP); rl_tv_title.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); rl_tv_title.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); rl_tv_title.addRule(RelativeLayout.BELOW, R.id.rl_chart_list_bottom); rl_iv_headicon_left.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); rl_iv_headicon_left.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); rl_tv_msg_left.addRule(RelativeLayout.LEFT_OF, R.id.chart_list_item_headicon); text.setBackgroundResource(R.drawable.outgoing); String titleStr = df.format(new Date()) + "-" + msg.getUsermac(); title.setText(titleStr); } if (!TextUtils.isEmpty(msg.getHeadImage())) { image.setImageBitmap(CommonUtils.strConvertBitmap(msg .getHeadImage())); // 设置头像 } else { image.setImageResource(R.drawable.im); } String str = msg.getMessage(); // 消息具体内容 try { SpannableString spannableString = ExpressionUtil .getExpressionString(context, str, CommonUtils.PATTERN); text.setText(spannableString); } catch (Exception e) { e.printStackTrace(); } } } }

源码下载:Android聊天室应用

以上就是本文的全部内容,希望对大家学习Android软件编程有所帮助,也希望大家多多支持脚本之家。

时间: 2024-09-26 17:37:22

Android编写简单的聊天室应用的相关文章

Android编写简单的聊天室应用_Android

最近写了一个简单的聊天室应用,可以发送表情,更改头像这些功能.主要技术点就是怎样把表情图片放到textview等Ui控件中展示.这里废话不多说,下面是效果图:  这里主要讲下怎样把文本替换到表情,先说下思路,首先我们的图片是保存在本地资源目录drawable中而所有的资源文件都是R这个类来管理,所以我们可以利用正则表达式找出图片id包装成ImageSpan然后把ImageSpan放到SpannableString中,最后把SpannableString放入edittext中,下面是源码: pac

用nodejs实现一个简单的聊天室

今天我来实现一个简单的聊天室,后台用nodejs, 客户端与服务端通信用socket.io,这是一个比较成熟的websocket框架. 初始工作 安装express, 用这个来托管socket.io,以及静态页面,命令npm install express --save,--save可以使包添加到package.json文件里. 安装socket.io,命令npm install socket.io --save. 编写服务端代码 首先我们通过express来托管网站,并附加到socket.io

Android 基于Socket的聊天室实例_Android

Socket是TCP/IP协议上的一种通信,在通信的两端各建立一个Socket,从而在通信的两端之间形成网络虚拟链路.一旦建立了虚拟的网络链路,两端的程序就可以通过虚拟链路进行通信. Client A  发信息给 Client B ,  A的信息首先发送信息到服务器Server ,Server接受到信息后再把A的信息广播发送给所有的Clients 首先我们要在服务器建立一个ServerSocket ,ServerSocket对象用于监听来自客户端的Socket连接,如果没有连接,它将一直处于等待

用ASP建立一个简单的聊天室

聊天室|聊天室     经过一个阶段的asp学习,下面我们结合所学过的内容建立一个最简单的聊天室,虽然很简单,但是大家可以通过他来掌握一个聊天室建立的基本过程,并且可以不断的完善其功能. 下面介绍其主要步骤: 1,添加Global.asa文件里面的代码.这部分代码主要处理Application_onStart事件,在此事件中,定义了一个有15个元素的数据,并把它赋给了一个Application对象的属性.Global.asa文件的内容如下. <SCRIPT LANGUAGE="VBScri

Flex和java的socket通信(四)一个简单的聊天室

服务端:java jdk1.5 使用工具:eclipse3.2 客户端:使用工具flex 2 目的:做一个简单的聊天室,用来实现消息广播. 服务端: 客户端:

ASP建立一个简单的聊天室_应用技巧

经过一个阶段的asp学习,下面我们结合所学过的内容建立一个最简单的聊天室,虽然很简单,但是大家可以通过它来掌握一个聊天室建立的基本过程,并且可以不断的完善其功能.下面介绍其主要步骤: 1,添加Global.asa文件里面的代码.这部分代码主要处理Application_onStart事件,在此事件中,定义了一个有15个元素的数据,并把它赋给了一个Application对象的属性.Global.asa文件的内容如下. <SCRIPT LANGUAGE="VBScript" RUNA

Java基于UDP协议实现简单的聊天室程序_java

最近比较闲,一直在抽空回顾一些Java方面的技术应用. 今天没什么事做,基于UDP协议,写了一个非常简单的聊天室程序. 现在的工作,很少用到socket,也算是对Java网络编程方面的一个简单回忆.  先看一下效果:   实现的效果可以说是非常非常简单,但还是可以简单的看到一个实现原理.  "聊天室001"的用户,小红和小绿相互聊了两句,"聊天室002"的小黑无人理会,在一旁寂寞着.  看一下代码实现:  1.首先是消息服务器的实现,功能很简单:•将客户端的信息(进

Android编写简单的网络爬虫

一.网络爬虫的基本知识 网络爬虫通过遍历互联网络,把网络中的相关网页全部抓取过来,这体现了爬的概念.爬虫如何遍历网络呢,互联网可以看做是一张大图,每个页面看做其中的一个节点,页面的连接看做是有向边.图的遍历方式分为宽度遍历和深度遍历,但是深度遍历可能会在深度上过深的遍历或者陷入黑洞.所以,大多数爬虫不采用这种形式.另一方面,爬虫在按照宽度优先遍历的方式时候,会给待遍历的网页赋予一定优先级,这种叫做带偏好的遍历. 实际的爬虫是从一系列的种子链接开始.种子链接是起始节点,种子页面的超链接指向的页面是

Android 基于Socket的聊天室实例

Socket是TCP/IP协议上的一种通信,在通信的两端各建立一个Socket,从而在通信的两端之间形成网络虚拟链路.一旦建立了虚拟的网络链路,两端的程序就可以通过虚拟链路进行通信. Client A  发信息给 Client B ,  A的信息首先发送信息到服务器Server ,Server接受到信息后再把A的信息广播发送给所有的Clients 首先我们要在服务器建立一个ServerSocket ,ServerSocket对象用于监听来自客户端的Socket连接,如果没有连接,它将一直处于等待