先来看一下效果图:
点击图一底部的回复后,出现图二效果。软键盘弹出,上面显示出一个布局,包括输入框和功能按钮等。
先说下我的心路历程吧,原来并没想设置一个新的布局在软键盘上,而是希望软键盘弹出的时候把底部的那个布局直接顶上去。这个其实比较容易实现,只需要设置活动的属性:
android:windowSoftInputMode="adjustPan"
这个属性设置了与软键盘相关的一些操作,详见http://blog.csdn.net/twoicewoo/article/details/7384398。这里设置的值表示唤出软键盘时必须留出输入框的空间,也就是软键盘弹出时如果edittext在下面,整个布局就会被软键盘顶上去,不会遮挡。
但是这里出现了一个问题,如果要点击的输入框在上面呢(列表中的回复),这时候控制布局滑下来,把输入框滑到软键盘正上方的操作就会很复杂。
所以改变思路,设置一个新布局,默认为gone,在用户点击回复后随软键盘弹出。过程是这样的:先让新布局设置为visiable,然后给新布局中的edittext焦点,然后根据这个edittext弹出软键盘。
点击事件:
@OnClick(R.id.tvComment)
public void comment(){
llEdit.setVisibility(View.VISIBLE);
et.requestFocus();
showKeyBoard();
}
弹出软键盘:
protected void showKeyBoard() {
if (mInputMethodManager == null) {
mInputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
}
mInputMethodManager.showSoftInput(et,0);
}
showSoftInput的第一个参数就是目标edittext,软键盘会把他顶在自己上面。这样就可以实现弹出效果了,但是还要解决随着软键盘收回,布局消失的问题,其实就是软键盘收回的监听。
需要用到根布局的一个监听器onGlobalLayoutListener,在每次布局变化的时候调用,因为软键盘弹出会挤压布局的空间,收回又会让这个空间扩大:
final View view=window.getDecorView();
view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect rect=new Rect();
view.getWindowVisibleDisplayFrame(rect);
int displayHeight=rect.bottom-rect.top;
int maxHeight=view.getHeight();
int height=maxHeight-displayHeight;
if (height<=200&&height!=lastHeight&&number>1){
llEdit.setVisibility(View.GONE);
}
lastHeight=height;
number++;
}
});
这部分逻辑有点复杂,首先要用到两个值,maxHeight就是根布局的高度,displayHeight是当前可见的高度,也就是被挤压后软键盘上的那一部分(没挤压的时候两个值也不相等)。通过这个差值可以判断软键盘时弹出还是收回。这里200是个大致的值,小于就是收回。
原来我直接判断小于两百就隐藏掉布局,但是发现弹出的时候布局也被隐藏掉了。原来是因为布局设置为visiable的时候也调用了这个方法,虽然通过打印发现这个差值根本没变。所以这里又加了两个int作判断,lastHeight是上一次的差值,number是第几次调用这个方法(第一次lastHeight是0,不能作判断)。
private int number=1;
private int lastHeight=0;
嘿嘿,这样就OK了。