即时聊天APP(五) - 聊天界面

设置界面没什么好说的,无非也就是加了个对话框来二次提醒用户,现在来讲讲聊天界面。

聊天界面初始化时会得到一个参数,就是对方的id,并设置在标题栏的位置,此界面也是使用RecyclerView来展示聊天消息。

首先为RecyclerView添加布局管理器(线性布局),并且为其添加适配器,写适配器之前先写类,消息类展示:

public class Msg extends LitePalSupport {
public static final int TYPE_RECEIVED = 0;    // 接收消息
public static final int TYPE_SENT = 1;        // 发送消息
private String Sender;
private String Receiver;
private String content;
private int type;
Msg(String content, int type) {
    this.content = content;
    this.type = type;
}
public static int getTypeReceived() {
    return TYPE_RECEIVED;
}
public static int getTypeSent() {
    return TYPE_SENT;
}
public String getContent() {
    return content;
}
public void setContent(String content) {
    this.content = content;
}
public int getType() {
    return type;
}
public void setType(int type) {
    this.type = type;
}
public String getSender() {
    return Sender;
}
public void setSender(String sender) {
    Sender = sender;
}
public String getReceiver() {
    return Receiver;
}
public void setReceiver(String receiver) {
    Receiver = receiver;
}
}  

然后写适配器,用于RecyclerView的展示以及各种事件的处理,首先定义一个内部类ViewHolder,继承自RecyclerView.ViewHolder,用来缓存子项的各个实例,提高效率,其余的我都用注释进行标注了:

public class MsgAdapter extends RecyclerView.Adapter{
private ListmMsgList;
static class ViewHolder extends RecyclerView.ViewHolder {
    LinearLayout leftLayout;
    LinearLayout rightLayout;
    TextView leftMsg;
    TextView rightMsg;
    // view表示父类的布局,用其获取子项
    ViewHolder(View view) {
        super(view);
        leftLayout = view.findViewById(R.id.left_layout);
        rightLayout = view.findViewById(R.id.right_layout);
        leftMsg = view.findViewById(R.id.left_msg);
        rightMsg = view.findViewById(R.id.right_msg);
    }
}
MsgAdapter(ListmsgList) {
    mMsgList = msgList;
}
/**
 * 创建 ViewHolder 加载 RecycleView 子项的布局
 * @param parent
 * @param viewType
 * @return
 */
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.msg_item, parent, false);
    return new ViewHolder(view);
}
/**
 * 为 RecycleView 子项赋值
 * 赋值通过 position 判断子项位置
 * 当子项进入界面时执行
 * @param holder
 * @param position
 */
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    Msg msg = mMsgList.get(position);
    if (msg.getType() == Msg.TYPE_RECEIVED) {
        // 如果是收到的消息,则显示左边的消息布局,将右边的消息布局隐藏
        holder.leftLayout.setVisibility(View.VISIBLE);
        holder.rightLayout.setVisibility(View.GONE);
        holder.leftMsg.setText(msg.getContent());
    } else if (msg.getType() == Msg.TYPE_SENT) {
        // 如果是发出的消息,则显示右边的消息布局,将左边的消息布局隐藏
        holder.rightLayout.setVisibility(View.VISIBLE);
        holder.leftLayout.setVisibility(View.GONE);
        holder.rightMsg.setText(msg.getContent());
    }
}
//返回子项个数
@Override
public int getItemCount() {
    return mMsgList.size();
}
}  

RecyclerView介绍完之后,返回来继续介绍聊天界面,初始化的时候也是先读取数据库,这里我做了限制,只查询出最近的50条聊天记录:

//读取数据库
private void read__db() {
msgList.clear();
msgL = LitePal.where("Sender = ? and Receiver = ?;",username,friend).find(Msg.class);
int count = msgL.size();
//判断消息长度,最多从数据库读取50条消息
if(count > 0 && count <=50 ){
    sel_50(0);
}else if(count > 50){
    sel_50(count - 50);
}
// 当有新消息时,刷新ListView中的显示
adapter.notifyItemInserted(msgList.size() - 1);
// 将ListView定位到最后一行
msgRecyclerView.scrollToPosition(msgList.size() - 1);
}
//查询截取50条数据
private void sel_50(int i){
for (; i < msgL.size(); i++){
    //加个异常
    try{
        Msg msgLi = new Msg(msgL.get(i).getContent(),msgL.get(i).getType());
        msgList.add(msgLi);
    }catch (Exception e) {}
}
}  

初始化完毕,当用户点击发送按钮的时候使用BmobIMConversation的sendMessage方法进行发送消息(具体请参考官方文档):

send.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //检查网络连接
            if(!NetWork.isNetConnection(Main.this))
                Toast.makeText(Main.this,"无网络连接!",Toast.LENGTH_SHORT).show();
            else{
                if(!MainActivity.isConnect)
                    Toast.makeText(Main.this,"连接服务器失败!",Toast.LENGTH_SHORT).show();
                //网络正常
                String content = inputText.getText().toString();
                if (!"".equals(content)) {
                    final Msg ms = new Msg(content, Msg.TYPE_SENT);
                    //连接成功,发送消息
                    BmobIMUserInfo info =new BmobIMUserInfo();
                    info.setAvatar("填写接收者的头像");
                    info.setUserId(friend);
                    info.setName("填写接收者的名字");
                    ms.setReceiver(friend);
                    ms.setSender(MyUser.getUni());
                    Tips.Receiver = friend;
                    //         BmobIMConversation conversationEntrance =
                    try{
                        BmobIM.getInstance().startPrivateConversation(info, new ConversationListener() {
                            @Override
                            public void done(BmobIMConversation c, BmobException e) {
                                if(e==null){
                                    //在此跳转到聊天页面或者直接转化
                                    mBmobIMConversation=BmobIMConversation.obtain(BmobIMClient.getInstance(),c);
                                    BmobIMTextMessage msg =new BmobIMTextMessage();
                                    msg.setContent(ms.getContent());
                                    //发送消息
                                    mBmobIMConversation.sendMessage(msg, new MessageSendListener() {
                                        @Override
                                        public void done(BmobIMMessage msg, BmobException e) {
                                            if (e != null) {
                                                Toast.makeText(Main.this, "发送失败", Toast.LENGTH_SHORT).show();
                                            }else{
                                                //添加消息
                                                add(ms);
                                            }
                                        }
                                    });
                                }else{
                                    Toast.makeText(Main.this, "开启会话出错", Toast.LENGTH_SHORT).show();
                                }
                            }
                        });
                    }catch (Exception e){}
                }
            }
        }
    });  

消息发送成功之后要进行本地数据库的更新,不光要更新消息列表,也要更新会话列表,使会话列表展示的是最新的消息:

//添加消息
public static void add(Msg msg){
if(msg.getType() == 1){
    msgList.add(msg);
    // 当有新消息时,刷新ListView中的显示
    adapter.notifyItemInserted(msgList.size() - 1);
    // 将ListView定位到最后一行
    msgRecyclerView.scrollToPosition(msgList.size() - 1);
    // 清空输入框中的内容
    inputText.setText("");
}else if(msg.getReceiver().equals(friend)) {
    msgList.add(msg);
    adapter.notifyItemInserted(msgList.size() - 1);
    msgRecyclerView.scrollToPosition(msgList.size() - 1);
}
//保存数据库
msg.save();
int len = msg.getContent().length();
ConList lis;
if(len > 15){
    String show = msg.getContent().substring(0,12);
    if(msg.getType() == 1)
        lis = new ConList(friend,"我:"+show+"......");
    else
        lis = new ConList(friend,"对方:"+show+"......");
}else {
    if(msg.getType() == 1)
        lis = new ConList(friend,"我:"+msg.getContent());
    else
        lis = new ConList(friend,"对方:"+msg.getContent());
}
lis.save();
}

原文地址:https://www.cnblogs.com/zqm-sau/p/10331959.html

时间: 2024-10-09 06:59:34

即时聊天APP(五) - 聊天界面的相关文章

20 行代码极速为 App 加上聊天功能

现在很多 App 都需要集成 IM 功能,今天就为大家分享一下集成 IM 基本功能的步骤.本文内容以 JMessage 为例.极光 IM ( JMessage ) = 极光推送 ( JPush ) + IM,本篇只论述其中的 IM 部分,为大家快速集成 IM 功能提供一个简明的范例. 我们先来看一下 IM 的基本功能与本文内容的对应关系: line 0:准备工作 下载 SDK 集成 SDK line 1:引入头文件 #import <JMessage/JMessage.h> JMessage

UIPro实例讲解之QQ2014 UI模仿系列五 - 聊天气泡

UIPro的宗旨是:让Windows UI开发像写小网页一样简单! 猜测了下QQ的气泡模式的实现方法: 分为两层,上面一层是windowless richedit, 透明模式:下面一层一个容器,包含有用户头像和气泡图片:下面一层随richedit一起滚动. 添加每一个paragraph后,可以得到这个段落的rang的左上角和右下角,从而得到该paragraph所在的矩形区域rect.然后就在下层的容器中,插入一个气泡,设置其rect:richedit滚动的时候,下层容器处理下事件. 未完待续 U

使用wcf的双工模式做的一个控制台聊天app

//wcf 服务 using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.ServiceModel.Web; using System.Text; namespace WcfService1 { // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文

Coinbase 推出基於以太坊的聊天 APP「Token」

Coinbase CEO Brian Armstrong 透过他的推特(Twitter)宣布推出一个名为「Token」的新产品,这个产品是一个手机聊天 APP,应用底层是利用以太坊来建设,使用者除了可以在上面发讯息,还可以传送 ETH 币给別人. Token已经正式推出,iOS 和 Android 用戶都可以下载使用.技术上,Token利用了 WhisperSystem 的 Signal Protocol 来加密用用户间的信息,这个技术连著名前美国 CIA 技术员爱德华·史诺登(Edward S

Android 极光IM-高级篇-玩聊天app诞生

距离上一次写 基础篇有了4个月,终于我写了一个 功能完善的即时通讯app,作为高级篇的担当出现.废话不多说,上图 app预览 ???? ???? ?? 实现功能 1.用户的登录注册 2.单聊,能清空聊天记录,且对于单人可以进行.语音通话,(这个部分我做的比官方demo要好得多,可以全局监听,但是没做群聊语音通话和视频通话) 3.群聊,能清空聊天记录.修改群名和修改群头像(只有群主才可以做) 4.消息类型:文字(包含系统表情).语音.图片.视频.文件.语音通话记录(自定义消息). 5.扫码或输入用

仿微信即时通讯APP源码(Android,IOS)

小圈子介绍    分享多样化:除了文字和多图分享,V4全面支持视频分享,还有移动互联必备的地理位置玩法,让分享更加有趣.    功能更丰富:全新功能等你发现!新增礼品中心.任务中心.找人.二维码--支持扩展,方便快捷.    像微信一样聊天:加强了聊天的扩展性,增加了地理位置.名片.语音.图片,同时还有更加期待的群聊功能.    更有趣:全新的任务中心.礼物商城.好玩的签到等游戏化元素,让你的社区更有趣.    想体验更多:附近的人.充值中心.分享到第三方.扫二维码......本产品源代码为其他

开发一款即时通讯App,从这几步开始

欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由腾讯云视频发表于云+社区专栏 关注公众号"腾讯云视频",一键获取 技术干货 | 优惠活动 | 视频方案 "晚上去哪吃饭啊?" 桌面上来自一条晚上约饭的对话框--QQ. 突然灵光一现,新出了优化的IM SDK,可以尝试着搭建一个类似QQ的即时通讯软件 01 注册账号 腾讯云官网 注册腾讯云账号,也可以使用QQ或者微信直接登陆 02 创建应用 选择[产品]→[云通信]→[立即使用]→[创建应用接入] 03

带后台的IM即时通讯App 全程MVP手把手打造

第1章 课程项目整体概述简单介绍课程适应人群以及主要的实现方案和课程的分节说明:除此之外展示APP使用效果同时了解IM相关协议并对比现有的IM实现方案.当然现如今IM已经不是一个APP而是一个SDK,趋近于嵌入到任何APP中使用:这也是IM推送聊天技术的主要使用场景....1-1 课程概述1-2 入门须知1-3 IM四大协议1-4 实现方案与选型 第2章 推送和存储平台准备这一章是推送方案的基础,在本章中选取了第三方平台以及文件存储平台.推送平台负责消息的送达,而OSS存储服务负责资源文件的存储

android asmack 注册 登陆 聊天 多人聊天室 文件传输

XMPP协议简介 XMPP协议(Extensible Messaging and PresenceProtocol,可扩展消息处理现场协议)是一种基于XML的协议,目的是为了解决及时通信标准而提出来的,最早是在Jabber上实现的.它继承了在XML环境中灵活的发展性.因此,基于XMPP的应用具有超强的可扩展性.并且XML很易穿过防火墙,所以用XMPP构建的应用不易受到防火墙的阻碍.利用XMPP作为通用的传输机制,不同组织内的不同应用都可以进行有效的通信. 这篇文章有基本的介绍,http://bl

即时通讯App怎样才能火?背后的技术原理,可以从这5个角度切入

欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由腾讯云视频发表于云+社区专栏 关注公众号"腾讯云视频",一键获取 技术干货 | 优惠活动 | 视频方案 社交场景 iMessage隐藏的省话费小秘密 融合通信原理 通过短信和IM的结合,可以实现从APP内到APP外的沟通.若你的朋友没有安装应用,你也可以在应用内,导入通讯录好友,给其发消息,只是这个"消息",会以短信的形式触达. 企业办公沟通场景 休假旅行,老板电话,这2个词总能凑一起 融合通信原理