参考:
http://stackoverflow.com/questions/17410499/difference-between-adjustresize-and-adjustpan-in-android
键盘弹出基本上开发中都会用到,之前用的比较简单,最多也就是Activity windowSoftInputMode标签中设置属性,没有深入研究。直到最近在解决键盘弹出导致界面闪烁的问题以及在做直播功能需要在键盘弹出时控制View的测量遇到一些问题,决定总结一下键盘弹出相关的知识点:
1、键盘弹出,收起的控制。
2、键盘弹出对View的影响。
3、监听键盘的弹出和收起动作,获取键盘高度。
4、自定义View不受键盘弹出的影响。
键盘行为的控制
一般情况,键盘的显示和隐藏都交由系统控制,比如,当EditText获取焦点时,键盘会弹出来,当用户按返回键时,键盘会收起来。但有时我们需要手动控制键盘的隐藏和显示,比如点击某个按钮显示或者隐藏键盘。这时就要通过InputMethodManager 来实现。
显示键盘:
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);
隐藏键盘:
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
View view = activity.getCurrentFocus();
imm.hideSoftInputFromWindow(view.getWindowToken(),0);
键盘的弹出和收起已经没有问题,现在需要关注的是,键盘弹起时,整个界面的行为,对此,Android提供了两种方式来设置:
1、在manifest Activity 标签设置:
<activity android:windowSoftInputMode="adjustResize"> </activity>
2、通过Java代码设置:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
Java代码有一个好处是可以在运行时改变windowSoftInputMode的值,比如某个界面默认设置的是adjustResize,但是某种情况下,需要设置为adjustPan。
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
if (checkedId == R.id.radioButtonAdjustPan) {
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
} else {
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
}
}
从上面的代码可以看出来,windowSoftInputMode是对应Window的一个属性,因此,我们也可以在Dialog,PopupWindow中设置这个属性:
public class TestDialog extends Dialog {
public TestDialog(Context context) {
super(context, R.style.AlertDialog);
init();
}
private void init() {
setContentView(R.layout.dialog_edit_test);
//getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
}
}
adjustPan和adjustResize对View的影响
windowSoftInputMode的可设定的值有很多个,但基本上最常用的也就adjustPan和adjustResize两种:
adjustPan:窗口大小不变,但是整个窗口向上平移。
adjustResize:窗口大小被压缩,给键盘留出空间。
键盘弹起时,这两者对应的表现形式很好理解,现在重点是研究当windowSoftInputMode分别设置这两个属性时,对界面中的View有什么影响,会调用View的哪些方法。
下面的KRelativeLayout 继承RelativeLayout ,没有做任何逻辑处理,只加了Log:
public class KRelativeLayout extends RelativeLayout {
public KRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public KRelativeLayout(Context context) {
super(context);
}
public KRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
Log.i("Keyboard", "KRelativeLayout onSizeChanged width&#