实训第八周(1)

本次主要整合所有P2P相关的内容,实现两人聊天界面的具体功能。

P2PChatActivity

1.onCreate:主要分为5部分:初始化当前聊天会话、初始化标题栏、初始化消息列表、初始化监听器、加载历史消息记录

@Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setStatusBarColor(R.color.app_blue_color);
        setContentView(R.layout.activity_p2p_chat);
        createChatSession();
        initTitle();
        ButterKnife.bind(this);

        mInputLayout.setLayoutListener(this);
        mInputLayout.bindInputLayout(this, mRecyclerView);

        initMsgList();
        initListener();

        // 注册监听
        NIMClient.getService(MsgServiceObserve.class)
                .observeReceiveMessage(mMsgReceiveObserver, true);
        NIMClient.getService(MsgServiceObserve.class)
                .observeMsgStatus(mMsgStatusObserver, true);
        NIMClient.getService(MsgServiceObserve.class)
                .observeAttachmentProgress(mProgressObserver, true);

        // 加载历史消息数据
        loadMessage();
    }
2.初始化当前聊天会话
private void createChatSession() {
        chatInfo = (NimUserInfo) getIntent().getSerializableExtra("NimUserInfo");
        NimUserInfo myInfo = NimUserHandler.getInstance().getUserInfo();
        mChatSession = new ChatSession();
        mChatSession.setSessionId(chatInfo.getAccount());
        mChatSession.setSessionType(SessionTypeEnum.P2P);
        mChatSession.setChatAccount(chatInfo.getAccount());
        mChatSession.setMyAccount(myInfo.getAccount());
        mChatSession.setChatInfo(chatInfo);
        mChatSession.setMyInfo(myInfo);

        mChatHandler = new ChatMsgHandler(this, mChatSession);
    }

3.初始化标题栏:

private void initTitle() {
        if (!TextUtils.isEmpty(mChatSession.getChatNick())) {
            setTitleBar(mChatSession.getChatNick(), true, true);
        } else {
            setTitleBar(mChatSession.getChatInfo().getName(), true, true);
        }
        mIvMenu.setImageResource(R.mipmap.people);
        // 打开详细资料界面
        mIvMenu.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(P2PChatActivity.this, FriendInfoActivity.class);
                intent.putExtra("NimUserInfo", chatInfo);
                intent.putExtra("FLAG", FriendInfoActivity.FLAG_PURE_SHOW_FRIEND);
                startActivity(intent);
            }
        });
    }

4.初始化消息列表:

private void initMsgList() {
        mLayoutManager = (LinearLayoutManager) mRecyclerView.getLayoutManager();
        mMsgList = new ArrayList<>();
        mListAdapter = new MessageListAdapter(this, mMsgList, mChatSession);
        mListAdapter.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(RViewHolder holder, IMMessage message) {
                switch (message.getMsgType()) {
                    case image:
                        showAttachOnActivity(ShowImageActivity.class, message);
                        break;
                    case audio:
                        playAudio(holder, message);
                        break;
                    case video:
                        //showAttachOnActivity(ShowVideoActivity.class, message);
                        break;
                    case location:
                        showAttachOnActivity(ShowLocActivity.class, message);
                        break;
                }
            }
        });

        mRecyclerView.setAdapter(mListAdapter);
        mRecyclerView.setLoadingListener(new MsgRecyclerView.OnLoadingListener() {
            @Override
            public void loadPreMessage() {
                loadMessage();
            }
        });
    }

5.初始化各类消息监听

 private void initListener() {

        mRecyclerView.setOnTouchListener(new MyTouchListener());

        final View decorView = getWindow().getDecorView();
        decorView.getViewTreeObserver()
                .addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                    private int previousKeyboardHeight = 0;
                    @Override
                    public void onGlobalLayout() {
                        Rect rect = new Rect();
                        getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
                        int displayHeight = rect.bottom;
                        int height = decorView.getHeight();
                        int keyboardHeight = height - displayHeight;
                        if (previousKeyboardHeight != keyboardHeight) {
                            boolean hide = (double) displayHeight / height > 0.8;
                            if (!hide){
                                //点击文本框后弹出键盘,消息滚到最后一条
                                mLayoutManager.scrollToPosition(mMsgList.size());
                            }
                        }
                    }
                });

        // 网易云信消息接收监听
        mMsgReceiveObserver = new Observer<List<IMMessage>>() {
            @Override
            public void onEvent(List<IMMessage> imMessages) {
                // 通过判断,决定是否添加收到消息的时间
                IMMessage imMessage = imMessages.get(0);
                if (mMsgList.isEmpty()) {
                    if (imMessage.getSessionType() == SessionTypeEnum.P2P
                            && imMessage.getSessionId().equals(mChatSession.getChatAccount())) {
                        mMsgList.add(mChatHandler.createTimeMessage(imMessage));
                    }
                } else {
                    IMMessage lastMsg = mMsgList.get(mMsgList.size() - 1);
                    if (imMessage.getSessionType() == SessionTypeEnum.P2P
                            && imMessage.getSessionId().equals(mChatSession.getChatAccount())
                            && imMessage.getTime() - lastMsg.getTime() > TEN_MINUTE) {
                        mMsgList.add(mChatHandler.createTimeMessage(imMessage));
                    }
                }

                // 将收到的消息添加到列表中
                int receiveCount = 0;
                for (IMMessage message : imMessages) {
                    if (message.getSessionType() == SessionTypeEnum.P2P
                            && message.getSessionId().equals(mChatSession.getChatAccount())) {
                        mMsgList.add(message);
                        receiveCount++;
                    }
                }

                if (receiveCount > 0) {
                    mListAdapter.notifyDataSetChanged();

                    // 对于整个 mListAdapter 来说,第0个 item 是 HeadView
                    // 即mMsgList的第 i 条数据,相当于mListAdapter来说是第 i+1 条
                    mLayoutManager.scrollToPosition(mMsgList.size());
                }
            }
        };
        // 网易云信消息状态监听
        mMsgStatusObserver = new Observer<IMMessage>() {
            @Override
            public void onEvent(IMMessage message) {
                // 收到消息状态更新,从后往前更新消息状态
                for (int i = mMsgList.size() - 1; i >= 0; i--) {
                    // 时间 item  UUid  为空
                    if (TextUtils.isEmpty(mMsgList.get(i).getUuid())) {
                        continue;
                    }
                    if (mMsgList.get(i).getUuid().equals(message.getUuid())) {
                        mMsgList.get(i).setStatus(message.getStatus());
                        mMsgList.get(i).setAttachStatus(message.getAttachStatus());

                        // 对于整个 mListAdapter 来说,第0个 item 是 HeadView
                        // 即 mMsgList 的第 i 条数据,相当于mListAdapter来说是第 i+1 条
                        mListAdapter.notifyItemChanged(i + 1);
                        break;
                    }
                }
            }
        };

        // 附件传输进度监听
        mProgressObserver = new Observer<AttachmentProgress>() {
            @Override
            public void onEvent(AttachmentProgress progress) {

            }
        };
    }

6.消息加载与加载回调

 private void loadMessage() {
        if (mMsgList.isEmpty()) {
            // 记录为空时,以当前时间为锚点
            IMMessage anchorMessage = MessageBuilder.createEmptyMessage(mChatSession.getSessionId(),
                    mChatSession.getSessionType(), System.currentTimeMillis());
            mChatHandler.loadMessage(anchorMessage, this);
        } else {
            // 否则,以最上一条消息为锚点
            IMMessage firstMsg = mMsgList.get(0);
            if (TextUtils.isEmpty(firstMsg.getUuid())) {
                firstMsg = mMsgList.get(1);
            }
            mChatHandler.loadMessage(firstMsg, this);//下面的loadSuccess/Fail即为ChatMsgHandler.OnLoadMsgListener的接口重写
        }
    }

    @Override
    public void loadSuccess(List<IMMessage> messages, IMMessage anchorMessage) {
        mRecyclerView.hideHeadView();

        boolean scroll = false;
        // 如果原本没有,为第一次加载,需要在加载完成后移动到最后一项
        if (mMsgList.isEmpty()) {
            scroll = true;
        }
        if (!messages.isEmpty()) {
            mMsgList.addAll(0, mChatHandler.dealLoadMessage(messages, anchorMessage));
            mListAdapter.notifyDataSetChanged();//mListAdapter为被观察者
        }
        if (scroll) {
            mLayoutManager.scrollToPosition(mMsgList.size());
        }
    }


    @Override
    public void loadFail(String message) {
        mRecyclerView.hideHeadView();
        ToastUtils.showMessage(this, "消息加载失败:" + message);
        Log.e(TAG, "load message fail:" + message);
    }

7.页面跳转回调(选择图片界面和定位界面)

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == SELECT_PHOTO) {
            if (resultCode == RESULT_OK) {
                String[] images = data.getStringArrayExtra("images");
                for (String path : images) {
                    sendMessage(mChatHandler.createImageMessage(path));
                }

            }
        } else if (requestCode == SELECT_LOCATION) {
            if (resultCode == RESULT_OK) {
                String address = data.getStringExtra("address");
                LatLonPoint loc = data.getParcelableExtra("location");
                sendMessage(mChatHandler.createLocMessage(loc, address));
            }
        }
    }
 /*** 消息发送 ***/
    //自己的界面用下述方式刷新,对方用网易云信消息接收监听mMsgReceiveObserver刷新
    private void sendMessage(IMMessage message) {

        if (mMsgList.isEmpty() ||
                message.getTime() - mMsgList.get(mMsgList.size() - 1).getTime() > TEN_MINUTE) {
            mMsgList.add(mChatHandler.createTimeMessage(message));
        }

        // 将新消息加入列表并刷新界面
        mMsgList.add(message);
        mListAdapter.notifyItemInserted(mMsgList.size());
        mLayoutManager.scrollToPosition(mMsgList.size());
        // 发送消息并监听消息发送状态
        NIMClient.getService(MsgService.class).sendMessage(message, false);
    }


8.输入面板事件回调:

 @Override
    public void sendBtnClick(String textMessage) {
        sendMessage(mChatHandler.createTextMessage(textMessage));
    }

    @Override
    public void photoTextBtnClick(String path){
        sendMessage(mChatHandler.createImageMessage(path));
    }

    @Override
    public void photoBtnClick() {
        Intent intent = new Intent(this, PhotoSelectActivity.class);
        startActivityForResult(intent, SELECT_PHOTO);
    }

    @Override
    public void locationBtnClick() {
        Intent intent = new Intent(this, SelectLocActivity.class);
        startActivityForResult(intent, SELECT_LOCATION);
    }


    @Override
    public void audioRecordFinish(String audioFilePath, long recordTime) {
        sendMessage(mChatHandler.createAudioMessage(audioFilePath, recordTime));
    }

    @Override
    public void audioRecordError(String message) {
        ToastUtils.showMessage(this, "录音出错:" + message);
    }

    @Override
    public void exLayoutShow() {
        mLayoutManager.scrollToPosition(mMsgList.size());
    }

    /***  标题栏返回按钮事件 *****/
    @OnClick(R.id.iv_back_btn)
    public void finishActivity() {
        KeyboardUtil.inputBmpList.clear();
        ChatInputLayout.currentBmpList.clear();
        this.finish();
    }

    //系统返回键
    public void onBackPressed() {
        KeyboardUtil.inputBmpList.clear();
        ChatInputLayout.currentBmpList.clear();
        this.finish();
    }

9.消息列表触摸事件:隐藏键盘

 /******  消息列表触摸事件   *******/
    private class MyTouchListener implements View.OnTouchListener {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                mInputLayout.hideOverView();
            }
            return false;
        }
    }

10.activity生命周期,注册或注销各类监听

 @Override
    protected void onResume() {
        super.onResume();
        // 设置当前聊天对象,即如果为mChatPersonAccount用户的消息,则不在通知了进行通知
        NIMClient.getService(MsgService.class).setChattingAccount(mChatSession.getChatAccount(),
                mChatSession.getSessionType());

        AudioPlayManager.resume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        // 当前无聊天对象,需要通知栏提醒
        NIMClient.getService(MsgService.class)
                .setChattingAccount(MsgService.MSG_CHATTING_ACCOUNT_NONE,
                        SessionTypeEnum.None);

        AudioPlayManager.pause();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 注销各类监听事件
        NIMClient.getService(MsgServiceObserve.class)
                .observeReceiveMessage(mMsgReceiveObserver, false);
        NIMClient.getService(MsgServiceObserve.class)
                .observeMsgStatus(mMsgStatusObserver, false);
        NIMClient.getService(MsgServiceObserve.class)
                .observeAttachmentProgress(mProgressObserver, true);

        AudioPlayManager.release();
    }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值