聊聊软键盘的那些事
程序员文章站
2022-05-05 10:05:42
...
①onDestroy
进行调用防止内存泄漏
/**
* 解决InputMethodManager内存泄露现象
*/
private static void fixInputMethodManagerLeak(Context destContext) {
if (destContext == null)
return;
InputMethodManager imm = (InputMethodManager) destContext.getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm == null)
return;
String[] arr = new String[]{"mCurRootView", "mServedView", "mNextServedView"};
Field f;
Object obj_get;
for (String param : arr) {
try {
f = imm.getClass().getDeclaredField(param);
if (!f.isAccessible()) {
f.setAccessible(true);
} // author: sodino mail:[email protected]
obj_get = f.get(imm);
if (obj_get != null && obj_get instanceof View) {
View v_get = (View) obj_get;
if (v_get
.getContext() == destContext) { // 被InputMethodManager持有引用的context是想要目标销毁的
f.set(imm, null); // 置空,破坏掉path to gc节点
} else {
// 不是想要目标销毁的,即为又进了另一层界面了,不要处理,避免影响原逻辑,也就不用继续for循环了
/*if (QLog.isColorLevel()) {
QLog.d(ReflecterHelper.class.getSimpleName(), QLog.CLR, "fixInputMethodManagerLeak break, context is not suitable, get_context=" + v_get.getContext()+" dest_context=" + destContext);
}*/
break;
}
}
} catch (Throwable t) {
t.printStackTrace();
}
}
}
②键盘遮挡EditText
假如EditText 基本贴近屏幕底部,弹出软键盘是会遮挡住EditText所填写的内容 ,如果清单文件设置windowSoftInputMode:adjustPan 则会把toolbar顶出屏幕
<1>用ScrollView进行包裹Edittext
<LinearLayout ... >
<Toolar ... />
<ScrollView ... >
<Edittext ... />
...
</ScrollView>
</LinearLayout>
<2>在根布局的layout下设置android:fitsSystemWindows="true"
<3>如果设置了状态栏透明,需要自定义了一个根布局并设置android:fitsSystemWindows="true"
// extends LinearLayout、RelativeLayout等写法一样
public class SoftInputLinearLayout extends LinearLayout {
private int[] mInsets = new int[4];
public SoftInputLinearLayout(Context context) {
super(context);
}
public SoftInputLinearLayout(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
@Override
public WindowInsets computeSystemWindowInsets(WindowInsets in, Rect outLocalInsets) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// Intentionally do not modify the bottom inset. For some reason,
// if the bottom inset is modified, window resizing stops working.
// TODO: Figure out why.
mInsets[0] = outLocalInsets.left;
mInsets[1] = outLocalInsets.top;
mInsets[2] = outLocalInsets.right;
outLocalInsets.left = 0;
outLocalInsets.top = 0;
outLocalInsets.right = 0;
}
return super.computeSystemWindowInsets(in, outLocalInsets);
}
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
mInsets[0] = insets.getSystemWindowInsetLeft();
mInsets[1] = insets.getSystemWindowInsetTop();
mInsets[2] = insets.getSystemWindowInsetRight();
return super.onApplyWindowInsets(insets.replaceSystemWindowInsets(0, 0, 0,
insets.getSystemWindowInsetBottom()));
} else {
return insets;
}
}
}
转载于:https://www.jianshu.com/p/9c66a8a83795
上一篇: linearLayout 配合merge动态添加子view的二种方式
下一篇: 聊聊支付通道的那些事