之前写过一篇文章 Android–>如何优雅的切换表情和键盘(原理), 没有看多的可以看看.
这个方案有一个问题, 当状态栏透明的时候, 就会出现问题. 而且也不支持在Dialog中使用.
实现方式也很简单, 但是代码逻辑很复杂, 不容易修改. 一不小心就会出错, 还找不到原因.
今天这篇文章, 让你焕然一新. 完全颠覆之前的方案.
前提,2个属性
android:windowSoftInputMode=“adjustResize”
android:fitsSystemWindows=“true”
会出现的坑:
如果通过简单的onSizeChange回调, 处理键盘弹出. 那么当状态栏透明之后, 这个方法是不会回调的.
因为, 当状态栏透明之后, 这个时候你的API已经满足了>=20. 这个时候:onApplyWindowInsets 此方法正好就是API 20的时候加入进来的.
从20开始, 系统改变了键盘弹出时, 布局的响应属性, 从原来的Height变化, 变成了最新的Padding变化.
也就是: 原来键盘弹出的时候, Layout的高度会变为原来的高度-键盘的高度;
而现在: Layout的高度不变, 但是PaddingBottom会变为键盘的高度.
这样就会导致onSizeChanged不会回调, 因为高宽都一样.
如果此时, 你要对不同的系统版本最适配, 提供对应的解决方案的话…那么,你将走向一条不归路.
其实,聪明的你, 应该也能想出解决方法.
以下是我的方案:
1:onMeasure
在测量内容高度和表情高度的时候, 根据键盘是否弹出, paddingBottom是否为空, 布局的height是否有变化.
决定内容的高度, 和 表情的高度. 主要是一定要确定内容的高度(要考虑键盘).
2:onLayout
有了高度, 就可以摆放内容布局和表情布局.
其实只要内容布局摆放合理, 表情布局在键盘弹出的时候可以任意摆放. 只要不影响内容就行.
就这么简单.
2019-8-20重构代码
- 兼容
低版本
安卓系统 - 支持最新版
微信
那样的动画 - 支持多
child
布局 - 支持
padding
处理 - 支持
SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
属性 - 支持
普通输入框
切换到安全密码输入框
- 支持布局
preview
- 内容布局支持
wrap_conent
,margin
属性.(高度很小时, 默认从Gravity.BOTTOM开始布局) - 支持
表情布局
恢复.(如:显示键盘之前是表情布局, 那么隐藏键盘后就会显示表情布局) - 支持
ViewPager
+多Fragment
中使用, 支持Activity
+多Fragment
中使用, 需要手动设置enableSoftInput
, 任何时候, 只要保证有且仅有一个SoftInputLayout
处于激活状态就行 - 支持
anim padding top
属性 - 支持动画回调, 可以入侵动画属性值
砖厂地址:
https://github.com/angcyo/ExKeyboardDemo