Android 软键盘遮挡问题解决
程序员文章站
2022-04-19 23:13:28
...
常规解决方式
在setContentView();
之前加入getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
非常规情况
上述方式设置失效时(在设置页面全屏,状态栏透明后设置会不起作用,项目中遇到过头疼了好久)
解决原理:
1.使用ViewTreeObserver.OnGlobalLayoutListener
注册监听视图树的观察者,监听可视区的高度变化来获取键盘高度
public class KeyBoardHeightUtil implements ViewTreeObserver.OnGlobalLayoutListener {
private final static String TAG = "KeyBoardHeightUtil";
private View mParentView;
private Rect mRect;
private int mScreenHeight;
private int mScreenStatusHeight;
private int mLastRectHeight;
private KeyBoardHeightChangeListener mKeyBoardChangeListener;
private boolean mSoftInputShowed;
private int mErrorHeight;
private boolean mFirst = true;
private int mLastKeyBoardHeight;
public KeyBoardHeightUtil(Context context, View parentView, KeyBoardHeightChangeListener listener) {
mParentView = parentView;
mRect = new Rect();
mFirst = true;
ScreenDimenUtil util = ScreenDimenUtil.getInstance();
mScreenHeight = util.getScreenHeight();
mScreenStatusHeight = util.getStatusBarHeight();
L.e(TAG, "---屏幕高度--->" + mScreenHeight);
L.e(TAG, "---状态栏高度--->" + mScreenStatusHeight);
mKeyBoardChangeListener = new WeakReference<>(listener).get();
}
@Override
public void onGlobalLayout() {
L.e(TAG, "-------onGlobalLayout--->");
if (mParentView != null && mRect != null) {
mParentView.getWindowVisibleDisplayFrame(mRect);
int curRectHeight = mRect.height();
if (mFirst) {
mFirst = false;
mScreenHeight = curRectHeight + mScreenStatusHeight;
mLastRectHeight = curRectHeight;
}
if (mLastRectHeight != curRectHeight) {
mLastRectHeight = curRectHeight;
int visibleHeight = curRectHeight + mScreenStatusHeight;
int keyboardHeight = mScreenHeight - visibleHeight;
mSoftInputShowed = keyboardHeight > mScreenHeight / 4;
if (mSoftInputShowed) {
keyboardHeight -= mErrorHeight;
} else {
if (keyboardHeight > 0) {
mErrorHeight = keyboardHeight;
}else {
mErrorHeight = 0;
}
keyboardHeight = 0;
}
visibleHeight = mScreenHeight - keyboardHeight;
if (mLastKeyBoardHeight != keyboardHeight) {
mLastKeyBoardHeight = keyboardHeight;
L.e(TAG, "-------可视区高度----->" + visibleHeight);
L.e(TAG, "-------键盘高度----->" + keyboardHeight);
if (mKeyBoardChangeListener != null) {
mKeyBoardChangeListener.onKeyBoardHeightChanged(visibleHeight, keyboardHeight);
}
}
}
}
}
/**
* 添加布局变化的监听器
*/
public void start() {
if (mParentView != null) {
mParentView.getViewTreeObserver().addOnGlobalLayoutListener(this);
L.e(TAG, "-------添加键盘监听--->");
Log.e("wzl", "-------添加键盘监听--->");
}
}
/**
* 移除布局变化的监听器
*/
public void release() {
if (mParentView != null) {
mParentView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
mParentView = null;
mRect = null;
mKeyBoardChangeListener = null;
L.e(TAG, "-------移除键盘监听--->");
}
public boolean isSoftInputShowed() {
return mSoftInputShowed;
}
}
2.根据键盘高度重新设置根布局的底部边距
private void onKeyBoardChanged(int keyboardHeight) {
if (mRootView != null) {
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) mRootView.getLayoutParams();
if (params.bottomMargin != keyboardHeight) {
params.bottomMargin = keyboardHeight;
mRootView.setLayoutParams(params);
scrollToBottom();//移动被软键盘遮挡的view
}
}
}
3.移动被软键盘遮挡的view
我这里移动的是recycleview
mLayoutManager.scrollToPositionWithOffset(mList.size() - 1, -DpUtil.dp2px(20));
KeyBoardHeightUtil 初始化方法
mKeyBoardHeightUtil = new KeyBoardHeightUtil(this, findViewById(android.R.id.content), this);
mRootView.post(new Runnable() {
@Override
public void run() {
if (mKeyBoardHeightUtil != null) {
mKeyBoardHeightUtil.start();
}
}
});
接口实现
@Override
public void onKeyBoardHeightChanged(int visibleHeight, int keyboardHeight) {
if (mPaused) {
return;
}
//监听到键盘高度后,改变底部边距
onKeyBoardChanged(keyboardHeight);
}
@Override
public boolean isSoftInputShowed() {
if (mKeyBoardHeightUtil != null) {
return mKeyBoardHeightUtil.isSoftInputShowed();
}
return false;
}
推荐阅读
-
Android getBackground().setAlpha遇到问题解决办法
-
Android中fragment嵌套fragment问题解决方法
-
Android 软键盘出现不适应的解决办法总结
-
Android ImageView 不显示JPEG图片的问题解决
-
android POST数据遇到的UTF-8编码(乱码)问题解决办法
-
Android加载图片内存溢出问题解决方法
-
Android getActivity()为空的问题解决办法
-
Android studio无法创建类和接口问题解决办法。提示 Unable to parse template "Class"
-
DownEditTextView【自定义Edittext对Android 软键盘向下的监听】
-
android添加依赖出现Failed to resolve:"你添加的依赖名" 或者出现 debug@Compileclasspath问题解决办法