美文网首页
fix dialog 输入法总是移动布局

fix dialog 输入法总是移动布局

作者: 王家匀匀 | 来源:发表于2020-11-30 14:25 被阅读0次

    需求:

    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, 不行, 输入法关不掉。

    至此,大功告成。

    相关文章

      网友评论

          本文标题:fix dialog 输入法总是移动布局

          本文链接:https://www.haomeiwen.com/subject/ciqrwktx.html