1、复杂ListView的展示

聊天模块其实就是一个复杂的ListView,在数据适配器中,从application中获取到当前登录的用户,与聊天消息中的from参数进行比较,如果两者相同则说明是自己发送的消息,那么ListView中就显示发送消息的布局,否则显示接收消息的布局。适配器的代码如下:

/*** 聊天消息的适配器* * @author ZHY* */
public class ChartMessageAdapter extends ArrayAdapter<QQMessage> {ImApp app;public ChartMessageAdapter(Context context, List<QQMessage> objects) {super(context, 0, objects);Activity activity = (Activity) context;app = (ImApp) activity.getApplication();}/*** 根据集合中的position位置,返回不同的值,代表不同的布局 0代表自己发送的消息 1代表接收到的消息* */@Overridepublic int getItemViewType(int position) {// 这个方法是给getView用得QQMessage msg = getItem(position);// 消息来自谁,如果消息来自我自己,说明是我发送的if (msg.from == app.getMyAccount()) {// 我自己的消息,发送return 0;} else {return 1;}}/*** 两种布局*/@Overridepublic int getViewTypeCount() {return 2;}class ViewHolder {TextView time;TextView content;ImageView head;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {int type = getItemViewType(position);if (0 == type) {// 发送的布局ViewHolder holder;if (convertView == null) {convertView = View.inflate(getContext(),R.layout.item_chat_send, null);holder = new ViewHolder();holder.time = (TextView) convertView.findViewById(R.id.time);holder.content = (TextView) convertView.findViewById(R.id.content);holder.head = (ImageView) convertView.findViewById(R.id.head);convertView.setTag(holder);} else {holder = (ViewHolder) convertView.getTag();}// 设置值QQMessage msg = getItem(position);holder.time.setText(msg.sendTime);holder.head.setImageResource(msg.fromAvatar);holder.content.setText(msg.content);return convertView;} else {// 接收的布局ViewHolder holder;if (convertView == null) {convertView = View.inflate(getContext(),R.layout.item_chat_receive, null);holder = new ViewHolder();holder.time = (TextView) convertView.findViewById(R.id.time);holder.content = (TextView) convertView.findViewById(R.id.content);holder.head = (ImageView) convertView.findViewById(R.id.head);convertView.setTag(holder);} else {holder = (ViewHolder) convertView.getTag();}// 设置值QQMessage msg = getItem(position);holder.head.setImageResource(msg.fromAvatar);holder.time.setText(msg.sendTime);holder.content.setText(msg.content);return convertView;}}
}

2、消息处理

在聊天页面中添加接收消息的监听,如果接收到的消息是聊天消息,那么就将接收到的消息添加到messages消息集合中,然后通知适配器数据发生了变化,进而刷新界面。当用户点击发送按钮的时候,封装消息,将消息发送个给服务器。聊天界面的代码如下:

/*** 聊天界面* * @author ZHY* */
public class ChartActivity extends Activity {@ViewInject(R.id.title)private TextView title;@ViewInject(R.id.listview)private ListView listView;@ViewInject(R.id.input)private EditText input;private ImApp app;private ChartMessageAdapter adapter;// 这是点击的用户,也就是你要发消息给谁private String toNick;// 要发送给谁private long toAccount;// y要发送的账号private long fromAccount;// 我的账号,我要跟谁睡聊天private String inputStr;// 聊天内容// 聊天消息的集合private List<QQMessage> messages = new ArrayList<QQMessage>();// 点击发送按钮的时候,获得输入框中的内容,将内容封装到messages集合中,聊调消息是一个QQMessageJava对象,一定包含四个字段@OnClick(R.id.send)public void send(View view) {// Toast.makeText(getBaseContext(), "ddadasf", 0).show();inputStr = input.getText().toString().trim();// 清空输入框input.setText("");final QQMessage msg = new QQMessage();if ("".equals(inputStr)) {Toast.makeText(getApplicationContext(), "不能为空", 0).show();return;}msg.type = QQMessageType.MSG_TYPE_CHAT_P2P;msg.from = fromAccount;msg.to = toAccount;msg.content = inputStr;msg.fromAvatar = R.drawable.ic_launcher;messages.add(msg);// 数据集合有了,创建适配器// 刷新消息if (adapter != null) {adapter.notifyDataSetChanged();}// 展示到最新发送的消息处if (messages.size() > 0) {listView.setSelection(messages.size() - 1);}// 发送消息到服务器--子线程ThreadUtils.runInSubThread(new Runnable() {public void run() {try {app.getMyConn().sendMessage(msg);} catch (IOException e) {e.printStackTrace();}}});}/*** 接收消息,使用监听器*/private OnMessageListener listener = new OnMessageListener() {public void onReveive(final QQMessage msg) {// 注意onReveive是子线程,更新界面一定要在主线程中ThreadUtils.runInUiThread(new Runnable() {public void run() {// 服务器返回回来的消息System.out.println(msg.content);if (QQMessageType.MSG_TYPE_CHAT_P2P.equals(msg.type)) {messages.add(msg);// 把消息加到消息集合中,这是最新的消息// 刷新消息if (adapter != null) {adapter.notifyDataSetChanged();}// 展示到最新发送的消息出if (messages.size() > 0) {listView.setSelection(messages.size() - 1);}}}});}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_chart);ViewUtils.inject(this);// 相当于findViewByIDapp = (ImApp) getApplication();// 开启监听app.getMyConn().addOnMessageListener(listener);// 聊天的界面是复杂的listView。发送消息的条目是item_chat_send.xml布局,接收到的消息现实的条目是item_chat_receive.xml布局/*** 聊天的消息 content "约不?" type chatp2p from 老王 to 大头*/// 获得从上一个界面获取的账号与昵称Intent intent = getIntent();toNick = intent.getStringExtra("nick");toAccount = intent.getLongExtra("account", 0);title.setText("与" + toNick + "聊天中");fromAccount = app.getMyAccount();// 我的账户adapter = new ChartMessageAdapter(this, messages);listView.setAdapter(adapter);}@Overrideprotected void onDestroy() {// TODO Auto-generated method stubsuper.onDestroy();app.getMyConn().removeOnMessageListener(listener);}
}

至此,基于Socket的Android即时通讯软件就介绍完了,功能很丑陋,原理基本能说得通,自己留一份备忘,同时也希望能帮到别人。源码的话,稍后整理发出来,整个项目运行起来的效果如下。有待完善的地方还有很多,望不吝赐教,与君共勉,共同进步!!!

点我下载源码

Android即时通讯--仿QQ即时聊天:(五)聊天模块相关推荐

  1. Android即时通讯--仿QQ即时聊天:(一)初识Socket

    1.即时通讯简介 即时通讯(Instant Messaging,简称IM)是一个终端服务,允许两人或者多人通过网络即时传递文字讯息.档案.语音等.简单的概括就是发送消息时,只要对方在线,就能立即接收到 ...

  2. 基于环信的仿QQ即时通讯的简单实现

    代码地址如下: http://www.demodashi.com/demo/11645.html 我的博客地址 之前一直想实现聊天的功能,但是感觉有点困难,今天看了环信的API,就利用下午的时间动手试 ...

  3. winform服务器消息推送,winform项目——仿QQ即时通讯程序12:服务端程序补充及优化...

    原标题:winform项目--仿QQ即时通讯程序12:服务端程序补充及优化 上一篇文章大概完成了服务端程序,今天继续做项目的时候发现还有一些功能没有做,还有几处地方不够完善.不做好就会影响客户端程序的 ...

  4. 高仿QQ即时聊天软件开发系列之三登录窗口用户选择下拉框

    上一篇高仿QQ即时聊天软件开发系列之二登录窗口界面写了一个大概的布局和原理 这一篇详细说下拉框的实现原理 先上最终效果图 一开始其实只是想给下拉框加一个placeholder效果,让下拉框在未选择未输 ...

  5. 仿微信 java IM即时通讯 | uni-app IM即时通讯 | vue IM即时通讯桌面端 | 源码出售

    仿微信 uniapp IM 即时通讯 源码 & 即时通讯知识小科普 源码,不加密,方便二开! 私有云服务,高效稳定,数据安全,无第三方服务 拓展性强,可拓展任意的消息体类型! 性能优秀,资源足 ...

  6. 即时通讯源码-即时通讯集群服务免费-通讯百万并发技术-Openfire 的安装配置教程手册-哇谷即时通讯集群方案-哇谷云-哇谷即时通讯源码

    即时通讯源码-即时通讯集群服务免费-通讯百万并发技术-Openfire 的安装配置教程手册-哇谷即时通讯集群方案-哇谷云 1,openfire开发环境配置 很久没有写点东西了.最近很烦心,领导不给力. ...

  7. 即时通讯:IM即时通讯实现原理

    即时通讯:IM即时通讯实现原理 IM技术概念 即时通讯(Instant Messenger,简称IM)软件多是基于TCP/IP和UDP进行通讯的,TCP/IP和UDP都是建立在更低层的IP协议上的两种 ...

  8. Android开发之仿QQ表情实现(上)

    大家晚上好,,小鹿又来了..最近小鹿特别忙,忙到没时间发表博客了(注:以下内容过于简单请大家不要喷,仅提供初学者学习) 今天发表两篇文章,分别是讲解模拟QQ表情的实现,先给大家看效果图,,,, 开始了 ...

  9. android的动态tab,Android自定义view仿QQ的Tab按钮动画效果(示例代码)

    话不多说 先上效果图 实现其实很简单,先用两张图 一张是背景的图,一张是笑脸的图片,笑脸的图片是白色,可能看不出来.实现思路:主要是再触摸view的时候同时移动这两个图片,但是移动的距离不一样,造成的 ...

最新文章

  1. Maven 的这 7 个问题你思考过没有?
  2. 作为数据科学家应该知道的11件事
  3. zookeeper 3.6.2启动报错:找不到或无法加载主类 org.apache.zookeeper.server.quorum.QuorumPeerMain
  4. 【Java面试题】汽水瓶问题
  5. C# XML反序列化与序列化举例:XmlSerializer(转)
  6. UPC2018组队训练赛第六场
  7. Mac 键盘符号整理
  8. cmake 常用变量和常用环境变量
  9. iis的web站点配置
  10. 2019 蓝桥杯省赛 A 组模拟赛(一)阶乘位数
  11. linux下pip换源——修改pip.conf文件
  12. 142. 环形链表 ||
  13. 记一次虚拟机共享文件夹的采坑之旅
  14. 三年经验前端社招面经——朴朴科技
  15. PPT:PowerPoint to Flash SDK:SWF
  16. 数据预处理之无量纲化、缺失值处理(三)
  17. Word控件Spire.Doc 【图像形状】教程(4) 用 C# 中的文本替换 Word 中的图像
  18. 【XSY3490】线段树(广义线段树,树上莫队)
  19. 发现4个神奇的软件,个个暗藏惊喜,不占内存亲测好评
  20. java 实现99乘法表

热门文章

  1. 北京交大计算机学院师资,赵瑞珍(计算机与信息技术学院)老师 - 北京交通大学 - 院校大全...
  2. 服务器硬件的基础知识,服务器硬件基础知识
  3. python制作游戏修改器_基于Python的游戏是如何制作的?
  4. 【学者风采】沈向洋 清华大学
  5. SDFormatter资源(免费)
  6. 弱引用WeakReference和软引用SoftReference
  7. 基于C#平台下利用POP3和SMTP协议的邮件归档系统
  8. 2021年麻城一中高考成绩查询,麻城一中2020年高考成绩 麻城一中2020年高考喜报...
  9. TS使用crypto-js进行加密
  10. linux7挂载光盘,redhat7挂载光盘