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

环信提供了一个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。这里就不再赘述了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,398评论 25 707
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,169评论 11 349
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,016评论 4 62
  • 站在地面看世界,满眼繁华;站在高山上看世界,是一片五彩的世界;坐在飞机上看世界,是如画的纸张;坐在飞船上看...
    北塔雪松阅读 341评论 0 12
  • 绝大多数人都能做的运动——踮脚! 别小看这个踮脚的动作,在踮脚过程中,小腿肌肉会有规律的收缩和舒畅,这就会最深层次...
    楚言初语阅读 554评论 0 0