即时通讯聊天页面,点击空白处隐藏键盘

最近开发一个类IM应用,碰到一个平时认为是想当然的功能,但实际做的时候却稍有卡壳。

需求:当键盘弹出,点击聊天页面空白处的时候,键盘隐藏

我们的本篇的重点是解决点击聊天页面空白处的问题,而非键盘的show/hiden,所以若有键盘相关需求的童鞋,可以先google下,有很多。

聊天页面的空白处,说明得排除可点击的区域,比如:
①、文字(点击后可能会有URL、电话号码的操作等)
②、头像(可能头像点击后会跳转个人信息)
③、图片(点击后有放大图片的操作)
④、视频(点击后播放视频)
⑤、卡片(比如分享的链接、红包等)
。。。。。

图是不是有点大。。。

思考过程:

初来拿到问题,想当然的认为监听RecyclerView的点击事件好了。
recyclerView.setOnClickListener()
⬇️
但是稍微一想,肯定不对啊,我们点击的虽然是空白区域,但其实点击的是每一条recycler view item。
⬇️
那么当消息不满一屏的时候,也就是recycler view item还没有覆盖一整屏的时候,空白区域是用recyclerView.setOnClickListener()来监听吗?

未铺满一屏的空白区域

经验证,也不是。
⬇️
于是想到肯定要处理view的touch事件了。
点击屏幕,判断当前点击区域是否为可点击控件(文字、头像、图片、视频、卡片等情况),如果不是,则父控件拦截事件、隐藏键盘;
当点击到上述可点击区域时,父控件下发事件,子控件(也就是上述可点击控件)拦截并消耗事件;

选择解决方案:

那么监听哪个view的touch事件呢?
1、Recycler item view?
的确,我们点击的就是item,那么理应处理item view的点击事件,对吧。
如果该item是文字类型,那么如果点击的是空白区域,父控件拦截并隐藏键盘;若我们点击的文字textview和头像imageview的时候,父控件就下发事件,交给文字或头像控件处理
但是,我们前面提过,还有当消息不满一屏的时候,即屏幕没有完全被消息item覆盖的时候,我们还得另外处理,头疼。。。

2、Activity?
网上看到的解决方案,重写Activity的onInterceptTouchEvent,把可点击的view,添加到一个list里面,然后处理onInterceptTouchEvent事件的时候,如果没有点击到该view,则拦截并隐藏键盘;若是,下发到子控件处理相关操作
大哥,要知道整个Activity里面包含的内容可并不只是有聊天内容啊,还有比如Toolbar、input操作区域、一些选择图片、emoji、发送按钮等功能区域,你要把这些也一个个添加到list里面,皇上还是赐我一个痛快的吧。。。

3、RecyclerView
这也是我最终选择的方案,我们直接来看代码吧

//给recyclerView添加touch listener
recyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
            @Override
            public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
                //获得action事件
                int action = e.getActionMasked();

                //当action是ACTION_DOWN的时候,处理事件
                if (action == MotionEvent.ACTION_DOWN) {
                    //根据你点击的点的横纵坐标,得到你点击的view
                    //这是Recyclerview自带的方法
                    View touchView = rv.findChildViewUnder(e.getX(), e.getY());
                    //Touch到了recyclerview没有item覆盖的区域
                    if (touchView == null) {
                        //隐藏键盘
                        Utils.forceHideKeyboard(ActivityChatNew.this, mInputView);
                        return false;
                    }
                    //需要单独处理event的view
                    View textView = touchView.findViewById(R.id.normal_message);
                    View imageView = touchView.findViewById(R.id.image_message);
                    View cardView = touchView.findViewById(R.id.card_root_view);
                    View emojiView = touchView.findViewById(R.id.chat_emoji_view);
                    View resendView = touchView.findViewById(R.id.chat_send_failed);
                    
                    if (textView == null && imageView == null
                            && cardView == null && emojiView == null
                            && resendView == null) {
                        Utils.forceHideKeyboard(ActivityChatNew.this, mInputView);
                        return false;
                    }

                    //判断点击的地方是否为可点击的控件,如果不是,隐藏键盘
                    if (!ConversationUtils.isTouchInView(textView, e)
                            && !ConversationUtils.isTouchInView(imageView, e)
                            && !ConversationUtils.isTouchInView(cardView, e)
                            && !ConversationUtils.isTouchInView(emojiView, e)
                            && !ConversationUtils.isTouchInView(resendView, e)) {
                        Utils.forceHideKeyboard(ActivityChatNew.this, mInputView);
                    }
                }
                //处理可点击控件的事件
                return false;
            }
            @Override
            public void onTouchEvent(RecyclerView rv, MotionEvent e) {
            }
            @Override
            public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
            }
        });

看看isTouchInView的代码,根据坐标判断点击的区域是否为可点击控件:

public static boolean isTouchInView(View view, MotionEvent event) {
        if (view == null) {
            return false;
        }
        int[] location = new int[2];
        view.getLocationOnScreen(location);
        int x = location[0];
        int y = location[1];
        return x < event.getRawX() && event.getRawX() < x + view.getWidth()
                && y < event.getRawY() && event.getRawY() < y + view.getHeight();
    }

OK,介绍完毕,是否清楚思路了?


请关注我的公众号~

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

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,569评论 25 707
  • 内容抽屉菜单ListViewWebViewSwitchButton按钮点赞按钮进度条TabLayout图标下拉刷新...
    皇小弟阅读 46,420评论 22 663
  • 郁闷,我可真黑,跟碳似的。尤其对比了十天前我(꒪.̸̸̸̸̸̸̸̸̸̸̸̸̸̸̸̸̸̸̸̸̸̨̨̨̨̨̨̨̨̨̨̨...
    菁菁zhen阅读 124评论 0 0
  • 菊花——不畏惧刺骨寒风,傲霜而立,在我国已有3000多年的栽培历史。从古至今,不管是文人墨客,还是寻常百姓,对菊...
    SoulCasualness阅读 586评论 0 1
  • 出瓜洲站不久,前往敦煌的路上,戈壁荒滩上突然冒出一片向日葵,金灿灿的向阳花,我差点认成油菜花,想来油菜花种在这里早...
    彩蛋旅行阅读 557评论 2 49