android开发键盘状态监听
来源:互联网 发布:cad软件下载 编辑:程序博客网 时间:2024/06/03 11:18
1.背景
相信大家在自己的项目中都会遇到EditText输入的问题,自然而然随之产生的就是让人头痛的键盘问题了,之所以说让人头疼是因为需求不同,设计不同,我们所要做的处理也不同,加上Google爸爸并没有针对键盘状态的API,所以只能靠我们自己处理。小白最近遇到的问题是:当键盘弹出的的时候,将输入框移到距离屏幕最上方20像素的地方,键盘收起时复位,所以有两个问题:
1.键盘弹出收起状态监听
2.将指定View移动到指定位置
来两张效果图:分别是弹出前和弹出后
第二个问题好处理,我们可以使用以下几种方式将View移动到指定位置
1.位移动画
2. 属性动画
3.scrollTo/scrollBy
4.改变View的param
本文的目的就是针对第一个问题进行处理,最后以工具类的的形式贴出,然后以接口的形式暴露出键盘改变后的状态。方便大家使用。
2.windowSoftInputMode
首先针对键盘与窗口的交互模式,Android提供了一个属性windowSoftInputMode,该属性为我们的输入法创建了一个Dialog,并且将该Dialog的Window的某些参数(如Gravity)进行了设置,使之能够在底部或者全屏显示。当我们点击输入框时,系统对活动主窗口进行调整,从而为输入法腾出相应的空间,然后将该Dialog显示在底部,或者全屏显示。
该属性可选的值有两部分,一部分为软键盘的状态控制,另一部分是活动主窗口的调整。
windowSoftInputMode的取值可以是下面中的一个或者一个state和一个adjust组合的形式,使用|连接。
- stateUnspecified:软键盘的状态(隐藏还是可见)没有确定,系统会根据主题当中的设置选取一个合适的状态(默认值),设置改属性之后和未设置属性值效果图一样,省略
- stateUnchanged:软键盘被保持无论它上次是什么状态,是否可见或隐藏,当主窗口出现在前面时
- stateHidden:用户选择activity时,软键盘总是被隐藏,适用于界面初始化键盘收起状态(从别的页面启动该页面)
- stateAlwaysHidden:软键盘总是被隐藏的,当该 Activity主窗口获取焦点时(即使从别的页面返回到该页面)
- stateVisible :软键盘是可见的,当那个是正常合适的时 (当用户导航到 Activity主窗口,即使该窗口没有EditText )
- stateAlwaysVisible :当用户选择这个 Activity时,软键盘是可见的,和stateVisible不同的是,当我们跳转到下个界面,如果下个页面软键盘是隐藏的,而我们再次回来的时候,软键盘就会显示出来
- adjustUnspecified:设置软键盘与软件的显示内容之间的显示关系。默认的设置模式,在这中情况下,系统会根据界面选择不同的模式
- adjustResize:窗口总是调整屏幕的大小用以保证软键盘的显示空间,设置这个模式以后,窗口的decorView 大小本身并不会改变,但是我们的内容区 contentView (id = android.R.content) 会相应的缩小,为键盘的显示挪出空间。软键盘弹出后 contentView 高度变化的差值即为软键盘高度。
- adjustPan: 窗口(DecorView) 大小不变。当获取到焦点的 EditText 位于屏幕下方。这个属性用的比较多,常常配合 ScrollView 来使用
- adjustNothing:窗口不会做任何调整,contentView 大小也不会改变
3.键盘弹出收起监听的原理
上面我们介绍过的属性,有一个属性特别重要,那就是:adjustSize,设置adjustSzie属性后,所在Activity的DecorView的大小会发生变化 ,那我们是不是可以利用这个变化来监测键盘状态呢?当然可以:
- 1.记录键盘未弹出时decorView 的高度,假设为:mOriginHeight,同时保存为变化之前的高度,假设为:mUnChangeHeight(这个可以监听ViewTreeObserver的OnGlobalLayoutListener接口-当一个视图树的布局发生改变时,可以被ViewTreeObserver监听)
- 2.当键盘弹出后,整个页面的视图树会进行重绘,再次获取decoView的高度,假设为mCurrentHeight,同时更新mUnChangeHeight(始终更新为最后一次Decoview的高度)
- 3.比较mOriginHeight和mCurrentHeight,若不相等则键盘状态发生变化,同时
- 4.若发生变化,则比较mCurrentHeight和mOriginHeight,若相等,则键盘收起,若不相等,则键盘弹出,且键盘高度为:mOriginHeight - mCurrentHeight
4.封装实现
1.新建一个类,实现ViewTreeObserver.OnGlobalLayoutListener接口
public class KeyboardManager implementsViewTreeObserver.OnGlobalLayoutListener {}
2.定义记录状态的变量
private int mOriginHeight;//记录DecoView的原始高度 private int mPreHeight;//记录DecoView变化之前的高度
3.onGlobalLayout回调中判断键盘状态(键盘状态改变时,由于设置的adjustResize会触发该回调)
@Override public void onGlobalLayout() { int currentHeight = mContentView.getHeight();//获取DecoView的高度 if (currentHeight == 0) { return; } boolean isChange = false;//默认记录为未改变 if (mUnChangeHeight == 0) { mUnChangeHeight = currentHeight;//DecoView的初始高度,页面的ViewTree第一次绘制完成时,会执行 mOriginHeight = currentHeight; } else { if (mUnChangeHeight != currentHeight) {//判断当前的高度是否和上一次的高度相等 isChange = true; mUnChangeHeight = currentHeight;//更新保存DecoView最后一次的高度 } else { isChange = false; } } if (isChange) { boolean isShow; int keyboardHeight = 0; if (mOriginHeight == currentHeight) { isShow = false; } else { keyboardHeight = mOriginHeight - currentHeight; isShow = true; } //根据isShow执行自己的操作 } }
5工具类和使用
/** * 键盘管理类 * Created by fanxudong on 2017/7/11. */public class KeyboardManager implements ViewTreeObserver.OnGlobalLayoutListener { private View mContentView; private int mOriginHeight; private int mUnChangeHeight; private KeyBoardChangeListener mKeyBoardListen; public static KeyboardManager getInstance(Activity activity){ return new KeyboardManager(activity); } public interface KeyBoardChangeListener { void onKeyboardChange(boolean isShow, int keyboardHeight); } public void addOnKeyBoardChangeListener(KeyBoardChangeListener keyBoardChangeListen) { this.mKeyBoardListen = keyBoardChangeListen; } public KeyboardManager(Activity activity) { if (activity == null) { return; } mContentView = findContentView(activity); if (mContentView != null) { addContentTreeObserver(); } } private View findContentView(Activity contextObj) { return contextObj.findViewById(android.R.id.content); } private void addContentTreeObserver() { mContentView.getViewTreeObserver().addOnGlobalLayoutListener(this); } @Override public void onGlobalLayout() { int currentHeight = mContentView.getHeight(); if (currentHeight == 0) { return; } boolean isChange = false; if (mUnChangeHeight == 0) { mUnChangeHeight = currentHeight; mOriginHeight = currentHeight; } else { if (mUnChangeHeight != currentHeight) { isChange = true; mUnChangeHeight = currentHeight; } else { isChange = false; } } if (isChange) { boolean isShow; int keyboardHeight = 0; if (mOriginHeight == currentHeight) { isShow = false; } else { keyboardHeight = mOriginHeight - currentHeight; isShow = true; } if (mKeyBoardListen != null) { mKeyBoardListen.onKeyboardChange(isShow, keyboardHeight); } } } public void destroy() { if (mContentView != null) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { mContentView.getViewTreeObserver().removeOnGlobalLayoutListener(this); } } }}
使用:
KeyboardManager.getInstance(this).addOnKeyBoardChangeListener(new KeyboardManager.KeyBoardChangeListener() { @Override public void onKeyboardChange(boolean isShow, int keyboardHeight) { if(isShow){ //弹出 }else { //收起 } } });
以上就是小白对键盘状态的总结,希望对大家有用!
- android开发键盘状态监听
- Android监听键盘状态变化
- Android-监听虚拟键盘状态
- android 监听键盘弹出收起状态
- android 学习笔记十二 监听键盘状态
- iPhone开发【二十八】监听键盘状态、输入法状态
- iOS开发中监听键盘状态、输入法状态
- android朋友圈监听键盘状态 点击空白区域隐藏键盘
- 监听键盘状态
- swift 监听键盘状态
- android应用开发 监听拨号键盘
- Android 关于监听键盘状态的一个偏方
- Android 监听手机键盘打开和关闭状态
- Android开发:实时监听网络状态
- android源码开发之监听来电状态
- android开发之手机屏幕状态的监听
- Android键盘处理-监听键盘状态并实现QQ拉出式弹出回复框。
- android 键盘按键监听
- 欢迎使用CSDN-markdown编辑器
- POJ 1422 Air Raid(二分图匹配+最小路径覆盖+匈牙利算法)
- 8.15(一个难忘的日子)
- LeetCode题-coins in a line
- redis 事务 理解和使用
- android开发键盘状态监听
- shell之sed
- XYNUOJ 确定比赛名次(拓补)
- Corn Fields POJ
- Libevent-2.1.8源码分析——日志消息
- Java设计模式之观察者模式
- HDOJ2117 简单模拟题
- 通过Nhibernate连接Mysql数据库
- linux中的http服务浅谈(2)