zoukankan      html  css  js  c++  java
  • 即时聊天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();
    }
  • 相关阅读:
    Node项目
    Angular模块/服务/MVVM
    Angular介绍1
    Node环境配置及Gulp工具
    Linux及Git介绍
    数据库MySQL
    ReactiveCocoa 监听枚举类型enumerate 或者 NSInteger类型
    ReactiveCocoa 监听布尔(BOOL)类型改变
    python3.7 urlopen请求HTTPS警告'CERTIFICATE_VERIFY_FAILED'解决办法
    Centos yum命令
  • 原文地址:https://www.cnblogs.com/zqm-sau/p/10331959.html
Copyright © 2011-2022 走看看