如果认真留意的话会发现,正常情况下,安卓版本的微信打开表情面板的高度总是能保持和键盘的高度一致(IOS的好像不一致),这样用户在进行键盘和面板的切换时能得到较好的用户体验。此外,微信也做了一定的处理,保证键盘和面板的切换比较流畅,不会出现跳动的现象。从这些细节可以体现出微信的用户体验还是做得很好的。首先上两张图感受一下:
          

第一张是把面板的高度写死,并且在面板和键盘的切换时没做特殊处理,这样面板和键盘的高度不一致而且切换时会出现跳动。第二张就是仿微信的效果。总结一下,这里需要完成的技术有两点:一是保证面板和键盘进行切换时高度保持一致,二是保证切换时不会出现跳动现象。

一. 面板的高度与键盘保持一致

一开始我不太明白这是怎么实现的,还以为有什么方法能够在程序运行时就获取到默认键盘的高度,然而查了一些资料后,发现是没有相应的API来获取的,而且经过试验后说明微信也不是提前就能够获取到键盘的高度的,而是要在进入聊天页后第一次打开键盘后才能获取到。前面说了是正常情况下能保证两者高度一致,下面说明什么情况下两者不一致。大部分人手机应该是用的第三方键盘,你可以做一下实验:
1.将键盘的高度调整到一个高到离谱的位置,再打开面板,这是会发现两者的高度不一致。这说明了当键盘的高度超过一定范围时,为了保证界面的美观,面板的高度会调整到一个默认的合适位置。
2.将键盘的高度调整到一个比较合适的位置,但跟系统键盘的高度不一致,然后在系统设置里把默认键盘设为系统键盘,再打开微信,先点开面板,再弹出键盘,这时你会发现两者的高度不一致,面板的位置仍保持在上一次的位置;打开一次键盘后再打开一次面板,这时你又会发现两者的高度又一致了,这就说明了微信也是需要在打开一次键盘后获取到其高度后再动态调整其面板的位置的,并没什么黑科技能提前获取。

那么现在的问题就变成了怎么在弹出键盘后获取其高度。其实也很简单,注意到弹出键盘后主布局是被压缩的,如果能获取到弹出前后主布局的高度,相减自然就是键盘的高度。核心代码如下:

root.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
//    监听根布局的高度变化@Overridepublic void onGlobalLayout() {int currentHeight = root.getHeight();if (screenHeight == 0) {screenHeight = root.getHeight();}
//        不等于屏幕高度或者记录的键盘高度,说明键盘高度发生了变化,需要更新记录的高度if (currentHeight != screenHeight && currentHeight != (screenHeight - inputMethodHeight)) {inputMethodHeight = screenHeight - currentHeight;isInputMethodHeightDirty = true;}}
});
…
@Override
public void onPause() {super.onPause();if (isInputMethodHeightDirty) {sharedPreferences.edit().putInt(PREF_KEY_INPUT_METHOD_HEIGHT, inputMethodHeight).commit();isInputMethodHeightDirty = false;}
}
…
@Override
public void setPanelHeight(int height) {if (height > MAX_HEIGHT || height <= MIN_HEIGHT) {return;} else if (height != morePanel.getMeasuredHeight()) {ViewGroup.LayoutParams params = morePanel.getLayoutParams();params.height = height;morePanel.setLayoutParams(params);ViewGroup.LayoutParams params2 = emojiPanel.getLayoutParams();params2.height = height;emojiPanel.setLayoutParams(params2);}
}

首先就是监听根布局高度的变化,通过addOnGlobalLayoutListener方法添加监听器,当根布局的高度发生变化时会执行onGlobalLayout回调。注意布局刚加载完毕时也会执行,因此可以获取弹出前的高度。当键盘弹出后会执行此方法,判断如果根布局高度不等于屏幕高度或者屏幕高度减去记录的键盘高度,说明键盘高度发生了变化,需要更新记录的高度。
获取到键盘高度后,在弹出面板时进行判断,如果当前面板的高度不等于键盘高度就进行调整使两者一致。最后再onPause()中判断如果键盘的高度发生变化的话就写回sharedPreference文件中,以后每次启动就可以通过sharedPreference文件获取之前记录的键盘高度。这样就使得面板高度与键盘高度保持一致。

二. 解决面板和键盘切换的跳动问题

首先要知道,界面跳动是由于软键盘的特性引起的。默认情况下,弹出键盘时会挤压主布局,此时如果又要进行面板的显示和隐藏,就会造成比较明显的跳动现象。要解决这个问题,就需要从键盘的行为下手。实际上,键盘的行为和Activity的windowSoftInputMode属性有关:
当属性为adjustResize时,软键盘弹出时会挤压根布局,这样可以保证输入法不会覆盖到输入框,默认的就是这种行为;
当属性为adjustNothing时,软键盘弹出时会直接覆盖到根布局上,根布局大小不变,这种情况输入法有可能会覆盖输入框。
那么在面板和键盘切换过程更改windowSoftInputMode属性,就能解决跳动问题:
1. 弹出面板时,将属性设为adjustNothing,这时如果弹出键盘,不会挤压根布局,由于两者高度一致,键盘就刚好覆盖了面板。
2. 隐藏面板时,将属性设为adjustResize,这时如果弹出键盘,会挤压根布局,这样就不会遮挡输入框。

核心代码如下:

@Override
public void showOrHideEmojiPanel(boolean showView) {if (showView) {setInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);mView.hideKeyboard();mView.showEmojiPanel();} else {mView.hideEmojiPanelDelayed();}
}
…
@Overridepublic void hideEmojiPanelDelayed() {
//        这里要delayed执行否则依然会跳动,因为隐藏面板的同时要弹出键盘,
//        弹出键盘有个延迟,如果在弹出键盘前执行的话就会造成跳动emojiPanel.postDelayed(new Runnable() {@Overridepublic void run() {hideEmojiPanel();
mPresenter.setInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);}},200);}

代码是用MVP架构写得,mView和mPresenter分别表示MVP中的V和P,其他别的逻辑我都省略了,其实核心的逻辑就是隐藏和显示面板时更改Activity的windowSoftInputMode属性。

这种方法是从自己的思路出发的,效果只用了一部华为荣耀机测试,不保证兼容,github上有位曾经在微信中工作过得大神开源了一个解决方案,地址为:https://github.com/Jacksgong/JKeyboardPanelSwitch 可以参考下,具体的方法还没研究过,以后有机会再看一下。

仿微信聊天界面——键盘与面板的切换相关推荐

  1. #解决仿微信聊天界面键盘遮盖聊天的界面

    解决仿微信聊天界面键盘遮盖聊天的界面 注意聊天界面的activity一定不能处于全屏模式 //第一步设置属性 <!--模拟的布局文件--><?xml version="1. ...

  2. php写的微信聊天界面,Android_Android高仿微信聊天界面代码分享,微信聊天现在非常火,是因其 - phpStudy...

    Android高仿微信聊天界面代码分享 微信聊天现在非常火,是因其界面漂亮吗,哈哈,也许吧.微信每条消息都带有一个气泡,非常迷人,看起来感觉实现起来非常难,其实并不难.下面小编给大家分享实现代码. 先 ...

  3. 高仿微信聊天界面长按弹框样式

    效果图 背景 在公司做的项目里面,刚好有需要用到微信聊天界面长按弹框样式这种UI的. 网上找了一下,没找到. Android现成的 ListPopupWindow又不能满足需求. 因此在非上班时间撸一 ...

  4. android 仿微信聊天界面 以及语音录制功能,Android仿微信录制语音功能

    本文实例为大家分享了Android仿微信录制语音的具体代码,供大家参考,具体内容如下 前言 我把录音分成了两部分 1.UI界面,弹窗读秒 2.一个类(包含开始.停止.创建文件名功能) 第一部分 由于6 ...

  5. android仿微信聊天功能,Android高仿微信聊天界面代码分享

    微信聊天现在非常火,是因其界面漂亮吗,哈哈,也许吧.微信每条消息都带有一个气泡,非常迷人,看起来感觉实现起来非常难,其实并不难.下面小编给大家分享实现代码. 先给大家展示下实现效果图: OK,下面我们 ...

  6. android 微信高仿,Android高仿微信聊天界面代码分享

    微信聊天现在非常火,是因其界面漂亮吗,哈哈,也许吧.微信每条消息都带有一个气泡,非常迷人,看起来感觉实现起来非常难,其实并不难.下面小编给大家分享实现代码. 先给大家展示下实现效果图: OK,下面我们 ...

  7. Android仿微信聊天界面

    今天说说android的仿微信聊天界面,我只想说两个字:坑爹 项目已经传到了github: https://github.com/hebiao6446/Hantu-android- 还好我写过iOS仿 ...

  8. h5仿微信聊天室weChatRoom|仿微信聊天界面

    html5仿微信聊天|h5仿微信聊天室|仿微信聊天界面|仿微信群聊/单聊 平时一闲下来就撸项目代码,最近一直在开发h5仿微信聊天项目,使用到了html5+css3+zepto+iscroll+swip ...

  9. 使用js实现的带输入状态的简单的仿微信聊天界面

    使用js实现的简单的仿微信聊天界面,实现固定的聊天回复功能,只能是固定的5句,但是回复的内容可以在代码的判断中进行修改. 实现的效果有:1.实现仿微信的聊天界面 2.实现仿微信的正在输入功能. 原理: ...

最新文章

  1. 百度重新定义「智能屏」,瞄准10后
  2. 销售易移动CRM助力制造业转型智能制造
  3. 调试器定位变量的原理
  4. STM32 基础系列教程 6 - PWM
  5. jQuery的遍历方法
  6. 男孩684分被清华预录取, 他的故事感动中国
  7. opengl纹理单元
  8. 《Arduino实战》——1.7 为代码编写注释
  9. Linux下查杀进程的方法说明
  10. php闭包 js闭包,JavaScript闭包与PHP闭包的区别是什么?
  11. MFC框架学习:《深入浅出MFC》阅读笔记
  12. Wireshark实验——了解PDU
  13. python 网络编程基础
  14. 命令启动edge浏览器且全屏
  15. matlab节点连通率,利用matlab仿真最小发射功率下wsn的连通性和覆盖率.docx
  16. 苹果公司对失败的总结和展望未来
  17. B站视频CC字幕提取和转换方法
  18. ChatGPT通俗导论:从RL之PPO算法、RLHF到GPT-N、instructGPT
  19. 机器学习之Pandas:Pandas介绍、基本数据操作、DataFrame运算、Pandas画图、文件读取与处、缺失值处理、数据离散化、合并、交叉表和透视表、分组与聚合、案例(超长篇,建议收藏慢慢看)
  20. 2n皇后问题 dfs

热门文章

  1. 云计算最高境界:手中无剑 心中有剑
  2. i.MX8MP平台开发分享(IOMUX篇)- 硬件原理
  3. 用java搭建自己的http服务器
  4. android 9.0 10.0 Launcher3添加负一屏(左一屏)功能
  5. 进入5G时代宽带业务将兴盛
  6. 简单明了的Promise基本知识点
  7. HTML5--地理定位与第三方工具百度地图的应用
  8. MPO接口光模块相关知识
  9. linux中egrep的用法,liunx中grep,egrep及相应的正则表达式和用法
  10. 创客c语言程序设计软件下载,C/C++程序设计学习与实验系统V2015.5.0.0官方免费版下载 - 下载吧...