Android键盘面板冲突 布局闪动处理方案
来源:互联网 发布:如何申请淘宝店铺 编辑:程序博客网 时间:2024/06/11 20:28
起源,之前在微信工作的时候,为了给用户带来更好的基础体验,做了很多尝试,踩了很多输入法的坑,特别是动态调整键盘高度,二级页面是透明背景,魅族早期的Smart bar等, 后来逐一完善了,考虑到拥抱开源,看业界还是有很多应用存在类似问题。就有了这个repo
之前有写过一篇核心思想: Switching between the panel and the keyboard in Wechat。
欢迎提交 Pull requests
- 尽量多的英文注解。
- 每个提交尽量的细而精准。
- Commit message 遵循: AngularJS's commit message convention。
- 尽可能的遵循IDE的代码检查建议(如 Android Studio 的 'Inspect Code')。
如何使用
在build.gradle
中引入:
compile 'cn.dreamtobe.kpswitch:library:1.4.4'
使用引导
非全屏主题情况下使用引导
所谓非全屏主题,就是
(activity.getWindow().getAttributes().flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) == 0
I. AndroidManifest
可直接参照: AndroidManifest.xml
对应的Activity,在
AndroidManifest
中配置android:windowSoftInputMode=adjustResize
<manifest ...> <application ...> <activity android:name=".activity.ChattingActivity" android:windowSoftInputMode=adjustResize"/> ... </application> ...</manifest>
II. 需要处理页面的layout xml
可直接参照: activity_chatting_resolved.xml
- 需要用到 最上层布局 (KPSwitchRootFrameLayout/KPSwitchRootLinearLayout/KPSwitchRootRelativeLayout)
- 需要用到 面板布局(KPSwitchPanelFrameLayout/KPSwitchPanelLinearLayout/KPSwitchPanelRelativeLayout)。
简单案例:
<?xml version="1.0" encoding="utf-8"?><!-- 可选用 KPSwitchRootLinearLayout、KPSwitchRootRelativeLayout、KPSwitchRootFrameLayout --><cn.dreamtobe.kpswitch.widget.KPSwitchRootLinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <!-- 布局内容 --> ... <!-- 可选用 KPSwitchPanelLinearLayout、KPSwitchPanelRelativeLayout、KPSwitchPanelFrameLayout --> <cn.dreamtobe.kpswitch.widget.KPSwitchPanelLinearLayout android:id="@+id/panel_root" android:layout_width="fill_parent" android:layout_height="@dimen/panel_height" android:visibility="gone"> <!-- 面板内容 --> ... </cn.dreamtobe.kpswitch.widget.KPSwitchPanelLinearLayout></cn.dreamtobe.kpswitch.widget.KPSwitchRootLinearLayout>
III. 需要处理页面的Activity:
可直接参照: ChattingResolvedActivity.java
- 处理一些事件(KPSwitchConflictUtil)
- 键盘状态(高度与显示与否)监听(KeyboardUtil#attach())
简单案例:
...// 面板Viewprivate KPSwitchPanelLinearLayout mPanelLayout;// 键盘焦点View,用于输入内容private EditText mSendEdt;// 用于切换键盘与面板的按钮Viewprivate ImageView mPlusIv;@Overridepublic void onCreate(Bundle saveInstanceState){ ... mPanelLayout = (KPSwitchPanelLinearLayout)findViewById(R.id.panel_root); mSendEdt = (EditText) findViewById(R.id.send_edt); mPlusIv = (ImageView) findViewById(R.id.plus_iv); /** * 这个Util主要是监控键盘的状态: 显示与否 以及 键盘的高度 * 这里也有提供给外界监听 键盘显示/隐藏 的监听器,具体参看 * 这个接口 {@Link KeyboardUtil#attach(Activity, IPanelHeightTarget, OnKeyboardShowingListener)} */ KeyboardUtil.attach(this, mPanelLayout); /** * 这个Util主要是协助处理一些面板与键盘相关的事件。 * 这个方法主要是对一些相关事件进行注册,如切换面板与键盘等,具体参看源码,比较简单。 * 里面还提供了一些已经处理了冲突的工具方法: 显示面板;显示键盘;键盘面板切换;隐藏键盘与面板; * * @param panelRoot 面板的布局。 * @param switchPanelKeyboardBtn 用于触发切换面板与键盘的按钮。 * @param focusView 键盘弹起时会给这个View focus,收回时这个View会失去focus,通常是发送的EditText。 */ KPSwitchConflictUtil.attach(mPanelLayout, mPlusIv, mSendEdt);}......// 如果需要处理返回收起面板的话@Overridepublic boolean dispatchKeyEvent(KeyEvent event){ if (event.getAction() == KeyEvent.ACTION_UP && event.getKeyCode() == KeyEvent.KEYCODE_BACK) { if (mPanelLayout.getVisibility() == View.VISIBLE) { KPSwitchConflictUtil.hidePanelAndKeyboard(mPanelLayout); return true; } } return super.dispatchKeyEvent(event);}
全屏主题情况下使用引导
所谓全屏主题,就是
(activity.getWindow().getAttributes().flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0
I. AndroidManifest
可直接参照: AndroidManifest.xml
对应的Activity,在
AndroidManifest
中配置android:windowSoftInputMode=adjustUnspecified
,或者不配置,默认就是这个模式。
II. 需要处理页面的layout xml
可直接参照: activity_chatting_fullscreen_resolved.xml
这边只需要用到一个 面板布局(KPSwitchFSPanelFrameLayout/KPSwitchFSPanelLinearLayout/KPSwitchFSPanelRelativeLayout)
<?xml version="1.0" encoding="utf-8"?>... ... <!-- 可选用 KPSwitchFSPanelFrameLayout、KPSwitchFSPanelLinearLayout、KPSwitchFSPanelRelativeLayout --> <cn.dreamtobe.kpswitch.widget.KPSwitchFSPanelFrameLayout android:id="@+id/panel_root" style="@style/Panel" android:visibility="gone"> ... </cn.dreamtobe.kpswitch.widget.KPSwitchFSPanelFrameLayout>...
III. 需要处理页面的Activity:
可直接参照: ChattingResolvedFullScreenActivity.java
- 主要是处理一些事件(KPSwitchConflictUtil)
- 键盘状态(高度与显示与否)监听(KeyboardUtil#attach())
- 在
onPause
时,记录键盘状态用于从后台回到当前布局,恢复键盘状态不至于冲突(IFSPanelConflictLayout#recordKeyboardStatus())
如下使用案例:
...// 面板Viewprivate KPSwitchFSPanelLinearLayout mPanelLayout;// 键盘焦点View,用于输入内容private EditText mSendEdt;// 用于切换键盘与面板的按钮Viewprivate ImageView mPlusIv;@Overridepublic void onCreate(Bundle saveInstanceState){ ... mPanelLayout = (KPSwitchFSPanelLinearLayout)findViewById(R.id.panel_root); mSendEdt = (EditText) findViewById(R.id.send_edt); mPlusIv = (ImageView) findViewById(R.id.plus_iv); /** * 这个Util主要是监控键盘的状态: 显示与否 以及 键盘的高度 * 这里也有提供给外界监听 键盘显示/隐藏 的监听器,具体参看 * 这个接口 {@Link KeyboardUtil#attach(Activity, IPanelHeightTarget, OnKeyboardShowingListener)} */ KeyboardUtil.attach(this, mPanelLayout); /** * 这个Util主要是协助处理一些面板与键盘相关的事件。 * 这个方法主要是对一些相关事件进行注册,如切换面板与键盘等,具体参看源码,比较简单。 * 里面还提供了一些已经处理了冲突的工具方法: 显示面板;显示键盘;键盘面板切换;隐藏键盘与面板; * * @param panelRoot 面板的布局。 * @param switchPanelKeyboardBtn 用于触发切换面板与键盘的按钮。 * @param focusView 键盘弹起时会给这个View focus,收回时这个View会失去focus,通常是发送的EditText。 */ KPSwitchConflictUtil.attach(mPanelLayout, mPlusIv, mSendEdt);}@Overrideprotected void onPause() { super.onPause(); // 用于记录当前的键盘状态,在从后台回到当前页面的时候,键盘状态能够正确的恢复并且不会导致布局冲突。 mPanelLayout.recordKeyboardStatus(getWindow());}...// 如果需要处理返回收起面板的话@Overridepublic boolean dispatchKeyEvent(KeyEvent event){ if (event.getAction() == KeyEvent.ACTION_UP && event.getKeyCode() == KeyEvent.KEYCODE_BACK) { if (mPanelLayout.getVisibility() == View.VISIBLE) { KPSwitchConflictUtil.hidePanelAndKeyboard(mPanelLayout); return true; } } return super.dispatchKeyEvent(event);}
基本原理
- 键盘高度计算,以及键盘是否显示的计算,参看:KeyboardUtil.KeyboardStatusListener#calculateKeyboardHeight、KeyboardUtil.KeyboardStatusListener#calculateKeyboardShowing。
- 处理闪动问题,参看: KPSwitchRootLayoutHandler,以及如果是非全屏主题用到的面板布局:KPSwitchPanelLayoutHandler;如果是全屏主题用到的面板布局: KPSwitchFSPanelLayoutHandler。
扩展阅读
Android Studio 提示与技巧(官方文档翻译)Android中软键盘弹出时关于布局的问题
android软键盘弹出引起的各种不适终极解决方案
介绍 Visual Studio 的 Android 模拟器
JavaScript 资源大全中文版
为您推荐
hadoop分布式集群搭建功能强大的验证码的Java类库:Patchca
CAS实现SSO(单点登录)
Struts2 json plugin实战2
Webpack + React 开发之路
更多
Android键盘
Android开发
Jacksgong / JKeyboardPanelSwitch
项目描述:For resolve the layout conflict when keybord & panel are switching (Android键盘面板冲突 布局闪动处理方案) — 查看更多内容..
- Android键盘面板冲突 布局闪动处理方案
- Android键盘面板冲突 布局闪动处理方案
- Android键盘面板冲突 布局闪动处理方案
- Android键盘面板冲突 布局闪动处理方案
- Android键盘面板冲突 布局闪动处理方案
- Android键盘切换闪动原理及解决方案
- android表情键盘完美解决闪动问题
- Android:完美解决 — 表情键盘与输入法键盘显示冲突方案
- React Native android 平台的键盘处理方案
- android之滑动面板布局
- android键盘监听方案
- Android 解决键盘把布局顶上去的冲突的问题
- Android 解决弹出输入法时布局闪动问题
- android 物理键盘布局
- 解决Android软键盘和表情面板切换界面闪动问题
- 解决Android软键盘和表情面板切换界面闪动问题(草稿)
- Android 解决输入法键盘遮盖布局问题,程序员不得不用的方案,快捷!
- Android 解决输入法键盘遮盖布局问题,程序员不得不用的方案,快捷!
- 关系型数据库 vs 非关系型数据库
- C语言中不可告人的(i++)+(i++)+(i++)!!!你发现了吗?
- 北京Cloudera Apache Hadoop 管理员培训9月开班
- Java环境配置
- U盘安装ubuntu 16.04遇到gfxboot.c32
- Android键盘面板冲突 布局闪动处理方案
- Cocos2d-js层的生命周期函数
- ObjectMapper--Jackson包中重要的Json转化方法
- Java程序的设计思想
- war包和jar包的区别
- Vector3 类简介
- 用css3的cursor:zoom-in/zoom-out实现微博看图片放大镜效果
- HDU 1042 A * B Problem Plus [FFT]
- PEP8 Python 编码规范