最近做一个类似微信朋友圈的功能,发现这个要做精细了,还是挺麻烦的,以评论为例。细细体验,它有如下特性:
- 点击评论的时候,才显示评论输入框。
- 输入框显示的位置紧紧靠在待评论消息的底部。
- 滑动其它地方,输入法和评论输入框自动隐藏。
- 点击back物理键,输入法和评论输入框自动隐藏。
其中1和3比较简单。逻辑如下:
- 问题1. 点击评论的时候,才显示评论输入框。
实现思想:评论输入框的默认状态为隐藏,点击评论按钮或者其它评论时,更改状态为显示,同时触发输入法弹出的操作
public static void showSoftInput(Context context, View view){
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
//imm.showSoftInput(view, InputMethodManager.SHOW_FORCED);
}
- 问题2. 滑动其它地方,输入法和评论输入框自动隐藏。
实现思想:给ListView一个Touch监听,出现滑动就隐藏评论输入框和输入法。
listView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
CommonUtils.hideSoftInput(context, mEditText);
mEditTextBody.setVisibility(View.GONE);
return false;
}
}
剩下两个问题是难点。
难点1:输入框显示的位置紧紧靠在待评论消息的底部。
初步想了三种方案:
- 每个item后面带一个评论输入框
- 评论输入框采用PopupWindow的形式实现,直接在待评论消息的底部弹出。
- 所有item共用一个评论输入框,该框放置在ListView父容器的底部
一一实践后,发现:
-
每个item后面带一个评论输入框
是行不通的,因为输入法没有办法自动弹出来,而点击输入框时,极容易触发Touch事件,导致输入框和发送按钮被隐藏 -
评论输入框采用PopupWindow的形式实现,直接在待评论消息的底部弹出。
也不行,因为PopupWindow内部输入法选中时,无法滑动下面的ListView,所以,被评论的消息很容易被遮挡住。这一块相关的代码可以参考这篇文章——popupwindow中EditText获取焦点后自动弹出软键盘 -
所有item共用一个评论输入框,该框放置在ListView父容器的底部
可行,做出来的效果和微信类似。
核心逻辑和相关代码如下:
- 计算 弹出键盘后评论输入框距离顶部的距离y1 和 所评论item底部距离顶部的距离y2,让ListView从y2滑动到y1
//注意,由于弹出输入法需要一定的时间,所以该方法要延迟500ms计算,500ms为经验值,仅供参考。
mEditTextBody.postDelayed(new Runnable() {
@Override
public void run() {
//16/5/31 计算移动距离
int[] position1 = new int[2];
itemBottomView.getLocationOnScreen(position);
Log.d(TAG, "srcViewRect.x = " + position1[0]);
Log.d(TAG, "srcViewRect.y = " + position1[1]);
int[] position2 = new int[2];
mEditTextBody.getLocationOnScreen(position2);
Log.d(TAG, "mEditTextBody.x = " + position2[0]);
Log.d(TAG, "mEditTextBody.y = " + position2[1]);
mListView.scrollBy(0, position1[1] - position2[1]);
}
}, 500);
难点2:点击back物理键,输入法和评论输入框自动隐藏。
目前没有找到解决方案,onBackPressed监听不到被输入法消耗的back键。
扩展阅读
在搜索相关问题是,找到一个知乎问题微信表情选择框的高度是如何做到在任何手机上适配输入法框高度的?,然后知道微信开发人员开源一个库用来计算输入法的高度,对这个问题没有太大作用,但对做输入法和表情之间的切换比较有参考价值,感兴趣的朋友可以看看,这个库是JKeyboardPanelSwitch。
Panda
2016-06-01
网友评论
public class XxxLinearLayout extends LinearLayout {
onResizeListener listener;
@Override
public boolean dispatchKeyEventPreIme(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
if (onResizeListener != null) {
onResizeListener.onResize();
}
return true;
}
return super.dispatchKeyEventPreIme(event);
}
}
使用这个方式会出现空白是咋么回事,求解答
这个方法会在按back之后,输入法响应之前执行,这里可以实现隐藏PopupWindow
@Override
public void onCancelDialog() {
//判断弹框是否为空
if (mPopWindow != null) {
mPopWindow.dismiss(); //弹框消失
mPopWindow = null; //赋空值
}
}
});