美文网首页
环信实现聊天界面查看大图左右轮滑效果

环信实现聊天界面查看大图左右轮滑效果

作者: 夏广成 | 来源:发表于2017-06-02 14:00 被阅读187次

    环信提供了一个easeUI库,其中实现了一些简单的聊天界面。但是产品需求却是要我们能够在聊天界面中点击图片,并且可以查看大图,在大图页面能够左右滑动,类似qq以及微信的效果。

    具体实现思路是,打开单人聊天界面时,开始从数据库中加载消息,直到消息加载完成,然后从所有的消息中获取属于图片的消息,然后保存到一个集合中,然后将这个集合中保存的图片地址,通过viewpager展示出来。

    思路理清之后,我们看一下相关的api

    一:EMConversation

    这个类代表一个用户的对话,从他这里可以获取相关的消息。

    image.png image.png image.png

    上面这两个方法,其中getAllMessages()代表回去内存中已经加载的所有消息。loadMoreMsgFromDB()返回的是我们从本地数据库中加载的消息。待会我们就是要从这里遍历得到所有的图片消息。

    二:EaseChatFragment

    EaseChatFragment他代表的就是当前我们打开的聊天页面。我们主要是在这里对图片信息进行筛选,保存。由于我们并不知道数据库中到底有多少信息,因此我们需要不停调用EMConversation的loadMoreMsgFromDB()来获取消息,直到我们读取完毕。我们这里选用来handler来处理循环读取。而handler处理循环读取的触发条件就是EMConversation初始化完成。

     protected void onConversationInit() {
            conversation = EMClient.getInstance().chatManager().getConversation(toChatUsername, EaseCommonUtils.getConversationType(chatType), true);
            conversation.markAllMessagesAsRead();
            // the number of messages loaded into conversation is getChatOptions().getNumberOfMessagesLoaded
            // you can change this number
            final List<EMMessage> msgs = conversation.getAllMessages();
            int msgCount = msgs != null ? msgs.size() : 0;
            if (msgCount < conversation.getAllMsgCount() && msgCount < pagesize) {
                String msgId = null;
                if (msgs != null && msgs.size() > 0) {
                    msgId = msgs.get(0).getMsgId();
                }
                conversation.loadMoreMsgFromDB(msgId, pagesize - msgCount);
            }
            handlerEM.sendEmptyMessage(111);
    
        }
    
    image.png
    1:创建一个Runnable来处理我们读到的消息。这个Runnable主要的思路是

    (1):判断当前是不是单一会话,如果是单一聊天,那么就先读取内存中的所有消息,
    (2):如果内存中的消息没有20条的话,因为我们在一开始的时候就试图从DB中加载20条消息,那就说明没有更多消息了。
    (3):如果内存中有20条消息,那么就继续从DB中读取,直到我们读到的数据不够20条为止。
    (4):需要注意我们在调用loadMoreMsgFromDB()的时候,传入的第一个参数是消息的id,我们应该取返回过来的集合当中的第一个消息的id,因为消息是从早到晚排列的,我们要想获得更早的消息,就需要用第一个消息的id。
    (5):环信有一个机制,就是当我们从DB中读取消息的时候,读出来的消息会保存到内存中。因此最终的消息,我们可以通过getAllMessages()来获取。

    //筛选出来的图片信息
        private ArrayList<String> imageuri;
    //我们最终通过从内存中获取所有消息。
        private List<EMMessage> allMessages;
    //临时存放从消息db中取出的消息
        private List<EMMessage> messagesEM;
    //判断是否有更多的消息了
        private boolean isMoreEM=true;
    //用来存放已经取出的消息,根据他的大小来判断有没有更多的消息
        ArrayList<EMMessage> emMessageArrayList =new ArrayList<>();
    Runnable runnableeEM=new Runnable() {
            @Override
            public void run() {
                try {
                    if (chatType == EaseConstant.CHATTYPE_SINGLE) {
                        if(emMessageArrayList.size()==0){
                            List<EMMessage> allMessages = conversation.getAllMessages();
                            messagesEM=conversation.loadMoreMsgFromDB(allMessages.get(0).getMsgId(),20);
                            emMessageArrayList.addAll(messagesEM);
                        }else{
                            messagesEM=conversation.loadMoreMsgFromDB(emMessageArrayList.get(0).getMsgId(),20);
                            emMessageArrayList.clear();
                            emMessageArrayList.addAll(messagesEM);
    
                        }
    
                    } else {
                        if(emMessageArrayList.size()==0){
                            List<EMMessage> allMessages = conversation.getAllMessages();
                            messagesEM=conversation.loadMoreMsgFromDB(allMessages.get(allMessages.size()-1).getMsgId(),20);
                            emMessageArrayList.addAll(messagesEM);
                        }else{
                            messagesEM=conversation.loadMoreMsgFromDB(emMessageArrayList.get(emMessageArrayList.size()-1).getMsgId(),20);
                            emMessageArrayList.clear();
                            emMessageArrayList.addAll(messagesEM);
                        }
    
                    }
                } catch (Exception e1) {
                    return;
                }
    
                if (emMessageArrayList.size() > 0) {
                    if (emMessageArrayList.size() != 20) {
                        isMoreEM=false;
                        //没有更多消息了
                        handlerEM.sendEmptyMessage(222);
                        Toast.makeText(getActivity(), getResources().getString(R.string.no_more_messages),
                                Toast.LENGTH_SHORT).show();
                    }else{
                        isMoreEM=true;
                        //还有更多消息
                        handlerEM.sendEmptyMessage(111);
                    }
                } else {
                    isMoreEM=false;
                        //没有更多消息了
                    handlerEM.sendEmptyMessage(222);
                    Toast.makeText(getActivity(), getResources().getString(R.string.no_more_messages),
                            Toast.LENGTH_SHORT).show();
                }
            }
        };
    
    2:创建一个handler来处理任务

    (1):当发送的是111表示还有更多消息,于是就继续从DB中获取。
    (2):当发送的是222表示没有更多消息了,我们就可以获取所有内存中的消息,然后遍历取到图片的消息。然后保存到集合中,当我们点击图片的时候使用。

     Handler handlerEM = new Handler() {
            @Override
            public void handleMessage(android.os.Message message) {
                switch (message.what){
                    case 111:
                        if(isMoreEM){
                            handlerEM.postDelayed(runnableeEM,1000);
                        }
                        break;
                    case 222:
                        allMessages = conversation.getAllMessages();
                        imageuri = new ArrayList<String>();
                        if(allMessages!=null){
                            for(EMMessage emMessage:allMessages){
                                if(emMessage.getBody() instanceof  EMImageMessageBody) {
                                    EMImageMessageBody imgBody = (EMImageMessageBody) emMessage.getBody();
                                    imageuri.add(imgBody.getRemoteUrl());
                                }
                            }
                        }
                        break;
                }
    
    
            }
        };
    
    

    三:EaseChatRowImage

    这个view代表的就是自定义的图片view,他展示在聊天页面中。在这个页面我们的实现思路
    (1):获取到保存在imageuri中的图片地址。
    (2):传递到查看大图的页面中。

     @Override
        protected void onBubbleClick() {
            Intent intent = new Intent(context, ViewBigImageActivity.class);
    //        File file = new File(imgBody.getLocalUrl());
            Bundle bundle = new Bundle();
            bundle.putInt("selet", 1);
    //        bundle.putInt("code", 0);
            ArrayList<String> imageuri = easeChatFragment.getImageuri();
            if(imageuri!=null&&imageuri.size()>0){
                for(int i=0;i<imageuri.size();i++){
                    if(TextUtils.equals(imageuri.get(i),imgBody.getRemoteUrl())){
                        bundle.putInt("code", i);
                    }
                }
            }
    
    //        if (file.exists()) {
    //            bundle.putBoolean("isLocal", true);
    //            imageuri.add(imgBody.getLocalUrl());
    //        } else {
    //            imageuri.add(imgBody.getRemoteUrl());
    //        }
            bundle.putStringArrayList("imageuri", imageuri);
            if (message != null && message.direct() == EMMessage.Direct.RECEIVE && !message.isAcked()
                    && message.getChatType() == EMMessage.ChatType.Chat) {
                try {
                    EMClient.getInstance().chatManager().ackMessageRead(message.getFrom(), message.getMsgId());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            intent.putExtras(bundle);
            context.startActivity(intent);
        }
    

    四:ViewBigImageActivity

    查看大图的页面,其实就是一个Viewpager,和一个ImageLoader。如果要实现放大缩小的功能的话,可以使用开源库uk.co.senab.photoview。这里就不再赘述了。

    相关文章

      网友评论

          本文标题:环信实现聊天界面查看大图左右轮滑效果

          本文链接:https://www.haomeiwen.com/subject/aqtxfxtx.html