EditText 如何处理软键盘与输入框的现显示隐藏关系 还有位置关系 通过设置windowSoftInputMode
windowSoftInputMode 还有下列属性
stateUnspecified:软键盘的状态并没有指定,系统将选择一个合适的状态或依赖于主题的设置
stateUnchanged:当这个activity出现时,软键盘将一直保持在上一个activity里的状态,无论是隐藏还是显示
stateHidden:用户选择activity时,软键盘总是被隐藏
stateAlwaysHidden:当该Activity主窗口获取焦点时,软键盘也总是被隐藏的
stateVisible:软键盘通常是可见的
stateAlwaysVisible:用户选择activity时,软键盘总是显示的状态
adjustUnspecified:默认设置,通常由系统自行决定是隐藏还是显示
adjustResize:该Activity总是调整屏幕的大小以便留出软键盘的空间
adjustPan:当前窗口的内容将自动移动以便当前焦点从不被键盘覆盖和用户能总是看到输入内容的部分
以上包括两种属性:state是软键盘的可见/隐藏 策略调整,adjust是界面对于软键盘出现的界面控件调整方式,
两种属性在Manifest中同时使用时 以 | 分隔。
使用方法 (以adjustPan为例):
通过设置windowSoftInputMode=adjustPan 或者 在activity的oncreate中setContentView之前写上getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
1. 一般情况下 ,我们使用windowSoftInputMode=adjustResize来保证点击EditText的时候弹出软键盘并顶起输入框,
adjustResize的调整UI方式是将 从屏幕底部往上一直到选中的EditText 的这一部分控件顶起,其他部分控件不变
2.如果使用 windowSoftInputMode=adjustPan,也会在点击 EditText后弹出软键盘并将输入框顶起,
但是并不会显示输入框以下的部分
,就是说此时输入框的位置正好贴在弹出的软键盘上方,如果输入框的下方还有内容的话,是会被软键盘遮挡的
,而且,最重要的一点,软键盘是通过粗暴地顶起整个UI的方式来占位的,这个时候很可能你就发现你的导航栏一起被顶不见了。所以这么粗暴的调整方式我觉得应该是不大适用的
3.如果是使用沉浸式布局的话,又发现使用adjustResize根本无法顶起EditText,输入框还是会被遮挡,如果使用adjustPan,整个UI又被顶的很难看。。。
4.哼,跟他搞这些花里胡哨的,烦了 ,我决定来硬的 我的项目布局是使用了沉浸式的,还是使用windowSoftInputMode=adjustResize
但是不顶出EdiText怎么办呢,那就自己实现监听软键盘的弹出,在键盘弹出后使用属性动画将EdiText移动到软键盘上方,并且在软键盘回收后再将ediText回复到原来的位置
这里的重点是监听到软键盘的弹出与回收,方法如下,这个方法的参数就是DectorView,可以通过布局内的任意一个View的
getRootView()方法得到。当软键盘出现时必然会将这个rootView覆盖,我们通过rootView.getWindowVisibleDiplayFrame()获得被覆盖后可见界面的Rect,并且通过rootView.getBottom()获得它原本的bottom坐标。很容易就得到覆盖在UI表面的软键盘的高度,这里我们主要是观察这个预设软键盘的最小高度为100dp,只要弹出高度大于这个值,我们就认为软键盘已经弹出了,并且使用属性动画将输入框所在控件移动适当高度,如果输入框在底部的话,只需向上移动这个高度即可
* 得到的Rect就是根布局的可视区域,而rootView.bottom是其本应的底部坐标值, * 如果差值大于我们预设的值,就可以认定键盘弹起了。这个预设值是键盘的高度的最小值。 * 这个rootView实际上就是DectorView,通过任意一个View再getRootView就能获得。 */ private boolean isKeyboardShown(View rootView) { final int softKeyboardHeight = 100; Rect r = new Rect(); rootView.getWindowVisibleDisplayFrame(r); DisplayMetrics dm = rootView.getResources().getDisplayMetrics(); int heightDiff = rootView.getBottom() - r.bottom; Log.e("hahah", heightDiff + ""); return heightDiff > softKeyboardHeight * dm.density; }
这里我们给DectorView添加一个GlobalLayoutListener,当它的可视状态发生变化的时候,就会调用onGlobalLayout,我们在这里判断软键盘的弹出与否并测量软键盘高度,调用属性动画相应地移动EditText所在控件
private void setListenerToRootView() { rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { boolean isOpen = isKeyboardShown(back.getRootView()); if(isOpen){ ObjectAnimator.ofFloat(editBar,"translationY",0,-height).setDuration(100).start(); haveChanged=true; }else{ if(haveChanged) { ObjectAnimator.ofFloat(editBar, "translationY", -height, 0).setDuration(100).start(); } } } }); }
哈哈哈哈哈 搞定收工