fix dialog 输入法总是移动布局
需求:
dialog固定高度、显示在屏幕底部,dialog中有一个EditText ,位置在布局上方且不会被键盘盖住。
所以要求,输入法不移动dialog布局,正常盖住即可。
问题:
dialog无论怎么设置,输入法总是会顶起布局,整个布局上移。
解决办法:
直接说答案----用activity代替dialog。
一定要注意 Android8.0 全屏透明页面不能设置页面方向,不然会奔溃。
参考 https://www.jianshu.com/p/aeccccd9117a
各种失败经验:
Dialog,AlertDialog,DialogFragment,AppCompatDialogFragment全部无效。
无论是 dialog.setView 还是dialog.setContentView.
无论是设置高度 march_parent,然后顶部透明;还是固定高度,gravity 为bottom。
无论是约束性布局、线性布局、FrameLayout作为根布局、即使是约束性布局(高度march_parent), 里面设置 app:layout_constraintBottom_toBottomOf="parent",键盘弹起来都会移动布局;
尝试了各种SoftInputMode,无论是adjustNothing、adjustResize、adjustPan
无论这个SoftInputMode设置的是activity还是dialog.window.setSoftInputMode都不行,在这里,adjustNothing效果等同于adjustPan。
android:windowSoftInputMode="adjustPan|stateHidden"
在activity中设置输入法监听,没有效果。在dialogFragment 中以及activity中设置
KeyboardUtils.fixAndroidBug5497(this.activity)都。。。
好吧,我认输。
那就用透明activity来代替dialog以及dialogFragment吧。
<!-- 弹框效果,设置全屏。 -->
<style name="activityBottomDialog" parent="@android:style/Theme.Black.NoTitleBar.Fullscreen">
<!-- 背景透明 -->
<item name="android:windowBackground">@android:color/transparent</item>
<!-- 是否透明 -->
<item name="android:windowIsTranslucent">false</item>
<!-- 模糊 -->
<item name="android:backgroundDimEnabled">false</item>
<!--全屏-->
<item name="android:windowFullscreen">true</item>
</style>
在清单文件中设置style:
<activity android:name=".YourActivity"
android:theme="@style/activityBottomDialog"
android:windowSoftInputMode="adjustNothing|stateHidden"
android:screenOrientation="portrait" />
这里要格外注意继承的theme 是哪个。如果activity继承自AppCompatActivity,非Theme.AppCompat子类就会奔溃:
Caused by: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.
同时还需要设置动画,从底部进入
https://blog.csdn.net/xuewater/article/details/36398803
修改后如下:
<style name="activityBottomDialog" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowFullscreen">true</item>
<item name="windowNoTitle">true</item>
<!--设置页面进出动效,现在给的是从下进下出效果-->
<item name="android:windowAnimationStyle">@style/animationTranslucentTranslate</item>
</style>
<style name="animationTranslucentTranslate" parent="@android:style/Animation.Translucent">
<item name="android:windowEnterAnimation">@anim/slide_in_bottom</item>
<item name="android:windowExitAnimation">@anim/slide_out_bottom</item>
<!--设置背景模糊效果,activity 中内容外部区域不设置背景色-->
<item name="android:backgroundDimEnabled">true</item>
</style>
//slide_in_bottom
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="200"
android:fromYDelta="100.0%"
android:toYDelta="0.0%" />
</set>
//slide_out_bottom
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="400"
android:fromYDelta="0.0%"
android:toYDelta="100.0%" />
</set>
anim 文件位于:src/main/res/anim。
这里如果不需要自定义动画效果,使用系统自带的@android:style/Animation.Translucent 样式也是可以的。效果基本是直接出来,可以看到代码是一个轻微移动和一个透明渐变效果。
还要注意:
activity 宽高都是match_parent;
activity中,顶部透明区域,要设置点击事件,关闭activity。
(模拟dialog.isCancelable=true,有内容区域设置clickable=true,就不会响应点击事件了)
那么,现在只差一个细节了:自动关闭输入法。
可以看到在小米8se\android 10 手机上,关闭弹框时输入法会自动消失,但是关闭弹框后 输入法又出来了(有的手机并不会在关闭页面时自动关闭输入法)。那么:
step1: 在此弹框页面 onDestroy 时关闭弹框:
private fun hideInputMethod() {
val imm: InputMethodManager? = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm?.hideSoftInputFromWindow(binding.edtSearch.windowToken, 0)
}
step2:设置上级activity输入法模式为stateAlwaysHidden(无论如何不显示输入法)
android:windowSoftInputMode="stateAlwaysHidden"
第二步不能省略,不然在8se手机上,会恢复输入法。
也尝试了 stateHidden, 不行, 输入法关不掉。
至此,大功告成。