在经过几年的经验累积之后,我终于决定整理一下曾经遇到的各种问题,给各位走在Android开发路上的朋友一点帮助,更多相关问题,请访问我的博客:http://blog.youkuaiyun.com/xiaoliluote 如果您对该问题有更多的解决方式,请留言,验证之后我会编辑博客
写之前,我想先吐槽一下,各大网站真的是垃圾水友多,一个人这么写,其它人就无脑抄,抄过去的好歹也自己试试效果啊,浪费大家的时间.
比如这样子的:
popupWindow.setSoftInputMode(PopupWindow.INPUT_METHOD_NEEDED);
popupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
您老在复制这段代码发布到自己的博客之前,能不能去试试? popupWindow.setSoftInputMode(PopupWindow.INPUT_METHOD_NEEDED); 这行代码虽然不会导致编译失败,但是它下面画着红色波浪线的,您眼瞎看不到吗? 正确的写法是setInputMethodMode,而不是setSoftInputMode.
笔者遇到的场景是:在Activity中点击购买,会从底部弹出PopupWindow,然后在该PopupWindow中有个EditText允许用户自行输入购买数量,此时弹出的软键盘,会覆盖掉popupWindow的内容,体验效果就很糟糕了.
在注册文件中设置android:windowSoftInputMode="adjustResize" 是没有用的,它只有在Activity的EditText里面才有用,这里是在PopupWindow里面.
好,吐槽完毕,下面说方案
1.上面的方案,放在popupWindow的show方法之前,在部分手机是有效的,也就是这样子用:
View view = LayoutInflater.from(this).inflate(R.layout.view_pop, null);
popview = new PopupWindow(view,
android.view.ViewGroup.LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT, true);
popview.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
popview.setFocusable(true);
// 设置点击其他地方就消失
popview.setOutsideTouchable(true);
popview.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
popview.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
popview.showAtLocation(ll_all, Gravity.BOTTOM
| Gravity.CENTER_VERTICAL, 0, 0);
2.笔者在亲测中发现,手里的一款乐视手机没得用,软件盘还是覆盖了PopupWindow的内容,如果您在测试中也遇到了该问题,那么用下面这个方案吧,应该是可以解决所有手机的问题.
这里借鉴了该网友的部分代码,附上链接,尊重别人的劳动成果:https://www.jianshu.com/p/9bba256f261f
但该网友的办法,在使用时,发现第一次弹出软键盘无效,原因是第一次弹出软键盘的时候,没有测量视图的高度,所以没有进入到软键盘弹出的监听方法,这里贴出修改过后的完整源代码:
import android.app.Activity;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewTreeObserver;
/**
* Created by KillaXiao on 2019/8/14.
* 监听软键盘的弹出与收起, 在部分手机测试到,popupwindow里面有edittext的时候,弹出软键盘,会覆盖掉从底部弹出的popupwindow内容
*/
public class SoftKeyBoardListener {
private View rootView; //activity的根视图
int rootViewVisibleHeight; //纪录根视图的显示高度
private OnSoftKeyBoardChangeListener onSoftKeyBoardChangeListener;
public SoftKeyBoardListener(Activity activity) {
//获取activity的根视图
rootView = activity.getWindow().getDecorView();
Rect r = new Rect();
rootView.getWindowVisibleDisplayFrame(r);
int visibleHeight = r.height();
rootViewVisibleHeight = visibleHeight;
//监听视图树中全局布局发生改变或者视图树中的某个视图的可视状态发生改变
rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
//获取当前根视图在屏幕上显示的大小
Rect r = new Rect();
rootView.getWindowVisibleDisplayFrame(r);
int visibleHeight = r.height();
System.out.println(""+visibleHeight);
if (rootViewVisibleHeight == 0) {
rootViewVisibleHeight = visibleHeight;
return;
}
//根视图显示高度没有变化,可以看作软键盘显示/隐藏状态没有改变
if (rootViewVisibleHeight == visibleHeight) {
return;
}
//根视图显示高度变小超过200,可以看作软键盘显示了
if (rootViewVisibleHeight - visibleHeight > 200) {
if (onSoftKeyBoardChangeListener != null) {
onSoftKeyBoardChangeListener.keyBoardShow(rootViewVisibleHeight - visibleHeight);
}
rootViewVisibleHeight = visibleHeight;
return;
}
//根视图显示高度变大超过200,可以看作软键盘隐藏了
if (visibleHeight - rootViewVisibleHeight > 200) {
if (onSoftKeyBoardChangeListener != null) {
onSoftKeyBoardChangeListener.keyBoardHide(visibleHeight - rootViewVisibleHeight);
}
rootViewVisibleHeight = visibleHeight;
return;
}
}
});
}
private void setOnSoftKeyBoardChangeListener(OnSoftKeyBoardChangeListener onSoftKeyBoardChangeListener) {
this.onSoftKeyBoardChangeListener = onSoftKeyBoardChangeListener;
}
public interface OnSoftKeyBoardChangeListener {
void keyBoardShow(int height);
void keyBoardHide(int height);
}
public static void setListener(Activity activity, OnSoftKeyBoardChangeListener onSoftKeyBoardChangeListener) {
SoftKeyBoardListener softKeyBoardListener = new SoftKeyBoardListener(activity);
softKeyBoardListener.setOnSoftKeyBoardChangeListener(onSoftKeyBoardChangeListener);
}
}
然后在PopupWindow中设置监听:
LinearLayout content_container;
//该方法先执行,测量一下布局的高度,笔者是自己写了一个class继承PopupWindow,固这里都是私有方法
private void initView(){
content_container = view.findViewById(R.id.content_container);
int width = View.MeasureSpec.makeMeasureSpec(0,
View.MeasureSpec.UNSPECIFIED);
int temp_height = View.MeasureSpec.makeMeasureSpec(0,
View.MeasureSpec.UNSPECIFIED);
content_container.measure(width, temp_height);
}
//布局高度测量完毕之后,设置监听
private void softInputListener(Activity mContext){
SoftKeyBoardListener.setListener(mContext, new SoftKeyBoardListener.OnSoftKeyBoardChangeListener() {
@Override
public void keyBoardShow(int height) {
ViewGroup.LayoutParams layoutParams = content_container.getLayoutParams();
//用父布局的原高度 + 软键盘弹出的高度 设置为父布局的新高度,软键盘就实际是覆盖了空白的部分,就不会遮挡住原popupWindow的内容了
layoutParams.height = content_container.getMeasuredHeight()+height;
content_container.setLayoutParams(layoutParams);
content_container.invalidate();
}
@Override
public void keyBoardHide(int height) {
//关闭软键盘时,再把布局高度设置回来
ViewGroup.LayoutParams layoutParams = content_container.getLayoutParams();
layoutParams.height = content_container.getMeasuredHeight()-height;
content_container.setLayoutParams(layoutParams);
content_container.invalidate();
}
});
}