输入adjustResize模式下键盘弹出dialog不能resize问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了输入adjustResize模式下键盘弹出dialog不能resize问题相关的知识,希望对你有一定的参考价值。

参考技术A 键盘的弹出模式可以通过设置windowSoftInputMode属性改变,总共有九种 这九种可以用|组合。

【1】stateUnspecified:软键盘的状态并没有指定,系统将选择一个合适的状态或依赖于主题的设置

【2】stateUnchanged:当这个activity出现时,软键盘将一直保持在上一个activity里的状态,无论是隐藏还是显示

【3】stateHidden:用户选择activity时,软键盘总是被隐藏

【4】stateAlwaysHidden:当该Activity主窗口获取焦点时,软键盘也总是被隐藏的

【5】stateVisible:软键盘通常是可见的

【6】stateAlwaysVisible:用户选择activity时,软键盘总是显示的状态

【7】adjustUnspecified:默认设置,通常由系统自行决定是隐藏还是显示

【8】adjustResize:该Activity总是调整屏幕的大小以便留出软键盘的空间

【9】adjustPan:当前窗口的内容将自动移动以便当前焦点从不被键盘覆盖和用户能总是看到输入内容的部分

今天说的问题即adjustResize模式下dialog中出现的问题。正常情况下adjustResize的模式下

键盘出现后屏幕绘制应用和height会变小,即键盘不会遮住任何应用ui,应用ui会重新测量绘制。

但是偶然间发现dialog在设置为adjustResize模式后 键盘的出现不会让dialog的height变小即键盘仍然会遮住dialog下部分的ui。

解决方案设置dialog属性windowIsFloating为false。

这个时候部分手机可能引来另一个问题actionbar处会有一小条非透明白色背景。

解决方案设置dialog的statusBarColor为透明。

<style name="BaseDialog" parent="Base.Theme.AppCompat">

    <item name="colorPrimary">@color/colorPrimary

    <item name="colorPrimaryDark">@color/colorPrimaryDark

    <item name="colorAccent">@color/colorAccent

    <item name="android:windowBackground">@android:color/transparent

    <item name="android:windowFrame">@null

    <item name="android:windowContentOverlay">@null

    <item name="android:backgroundDimEnabled">true

    <item name="android:windowIsTranslucent">true

    <item name="android:windowNoTitle">true

    <item name="android:windowCloseOnTouchOutside">true

    <item name="android:windowSoftInputMode">stateHidden|adjustResize

    <item name="android:windowFullscreen">false

    <item name="android:statusBarColor">@android:color/transparent

    <item name="android:colorBackgroundCacheHint">@null

    <item name="android:windowTitleStyle">@style/RtlOverlay.DialogWindowTitle.AppCompat

    <item name="android:windowTitleBackgroundStyle">@style/Base.DialogWindowTitleBackground.AppCompat

    <item name="android:windowIsFloating">false

    <item name="android:windowAnimationStyle">@style/Animation.AppCompat.Dialog

    <item name="windowActionBar">false

    <item name="windowActionModeOverlay">true

    <item name="listPreferredItemPaddingLeft">24dip

    <item name="listPreferredItemPaddingRight">24dip

    <item name="android:listDivider">@null

    <item name="android:buttonBarStyle">@style/Widget.AppCompat.ButtonBar.AlertDialog

    <item name="android:borderlessButtonStyle">@style/Widget.AppCompat.Button.Borderless

</style>

登录界面软键盘遮挡登入按钮 空间

如图效果

类似于QQ登入界面,软键盘弹出的时候,不遮挡登入按钮,整体的界面在软键盘之上

直接上干货

监听软键盘弹出及收起事件

步骤1。指定windowSoftInputMode =“adjustResize”

在AndroidManifest.xml中相应的Activity设置android:windowSoftInputMode =“adjustResize”,也可以在java代码中设置。

第2步。监听contentView宽高(布局)变化

使用这个帮助类

public class KeyBoardHelper 

    private Activity activity;
    private OnKeyBoardStatusChangeListener onKeyBoardStatusChangeListener;
    private int screenHeight;
    // 空白高度 = 屏幕高度 - 当前 Activity 的可见区域的高度
    // 当 blankHeight 不为 0 即为软键盘高度。
    private int blankHeight = 0;

    public KeyBoardHelper(Activity activity) 
        this.activity = activity;
        screenHeight = activity.getResources().getDisplayMetrics().heightPixels;
        activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
        if (activity.getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) 
            activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        
    

    public void onCreate() 
        View content = activity.findViewById(android.R.id.content);
        // content.addOnLayoutChangeListener(listener); 这个方法有时会出现一些问题
        content.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
    

    public void onDestory() 
        View content = activity.findViewById(android.R.id.content);
        content.getViewTreeObserver().removeOnGlobalLayoutListener(onGlobalLayoutListener);
    

    private OnGlobalLayoutListener onGlobalLayoutListener = new OnGlobalLayoutListener() 

        @Override
        public void onGlobalLayout() 
            Rect rect = new Rect();
            activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
            int newBlankheight = screenHeight - rect.bottom;
            if (newBlankheight != blankHeight) 
                if (newBlankheight > blankHeight) 
                    // keyboard pop
                    if (onKeyBoardStatusChangeListener != null) 
                        onKeyBoardStatusChangeListener.OnKeyBoardPop(newBlankheight);
                    
                 else  // newBlankheight < blankHeight
                    // keyboard close
                    if (onKeyBoardStatusChangeListener != null) 
                        onKeyBoardStatusChangeListener.OnKeyBoardClose(blankHeight);
                    
                
            
            blankHeight = newBlankheight;
        
    ;

    public void setOnKeyBoardStatusChangeListener(
            OnKeyBoardStatusChangeListener onKeyBoardStatusChangeListener) 
        this.onKeyBoardStatusChangeListener = onKeyBoardStatusChangeListener;
    

    public interface OnKeyBoardStatusChangeListener 

        void OnKeyBoardPop(int keyBoardheight);

        void OnKeyBoardClose(int oldKeyBoardheight);
    

具体的实现案例

xml布局文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/login_map"
    android:focusable="false"
    android:orientation="vertical">

    <LinearLayout
        android:id="@+id/layout_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="@dimen/padding_0"
            android:layout_marginTop="@dimen/padding_30"
            android:layout_weight="1"
            android:focusable="false">

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_margin="@dimen/padding_50"
                android:focusable="false"
                android:src="@drawable/login_welcome" />
        </LinearLayout>


        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="@dimen/padding_0"
            android:layout_weight="2"
            android:focusable="false"
            android:gravity="center"
            android:orientation="vertical">

            <EditText
                android:id="@+id/et_login_input"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/padding_20"
                android:background="@drawable/dialog_box"
                android:hint="@string/login_input"
                android:paddingBottom="@dimen/padding_15"
                android:paddingLeft="@dimen/padding_20"
                android:paddingTop="@dimen/padding_15"
                android:singleLine="true"
                android:textColor="@color/bg_white"
                android:textColorHint="@color/bg_white" />

            <TextView
                android:id="@+id/tv_login"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/padding_20"
                android:background="@drawable/login_button"
                android:focusable="false"
                android:gravity="center"
                android:padding="@dimen/padding_15"
                android:text="@string/login_text"
                android:textColor="@color/bg_white"
                android:textSize="@dimen/padding_20" />


        </LinearLayout>

        <TextView
            android:id="@+id/layout_bottom"
            android:layout_width="match_parent"
            android:layout_height="10dp"
            android:layout_alignParentBottom="true"
            android:text="" />
    </LinearLayout>

</RelativeLayout>

效果图

主要功能的代码(我这里是在fragment里面写的查找id省略)

//关键的代码
 @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) 
        View view = inflater.inflate(R.layout.fragment_login, container, false);
        initView(view);
        boardHelper = new KeyBoardHelper(getActivity());
        boardHelper.onCreate();
        boardHelper.setOnKeyBoardStatusChangeListener(onKeyBoardStatusChangeListener);
        layoutBottom.post(new Runnable() 
            @Override
            public void run() 
                bottomHeight = layoutBottom.getHeight();
            
        );
        return view;
    

    private KeyBoardHelper.OnKeyBoardStatusChangeListener onKeyBoardStatusChangeListener = new KeyBoardHelper.OnKeyBoardStatusChangeListener() 

        @Override
        public void OnKeyBoardPop(int keyBoardheight) 

            final int height = keyBoardheight;
            if (bottomHeight > height) 
                layoutBottom.setVisibility(View.GONE);
             else 
                int offset = bottomHeight - height;
                final ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) layoutContent
                        .getLayoutParams();
                lp.topMargin = offset;
                layoutContent.setLayoutParams(lp);
            

        

        @Override
        public void OnKeyBoardClose(int oldKeyBoardheight) 
            if (View.VISIBLE != layoutBottom.getVisibility()) 
                layoutBottom.setVisibility(View.VISIBLE);
            
            final ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) layoutContent
                    .getLayoutParams();
            if (lp.topMargin != 0) 
                lp.topMargin = 0;
                layoutContent.setLayoutParams(lp);
            

        
    ;

到此,问题搞定

以上是关于输入adjustResize模式下键盘弹出dialog不能resize问题的主要内容,如果未能解决你的问题,请参考以下文章

Android全屏状态下弹出输入法adjustResize无效的修复方案及踩坑指南

AndroidAndroid如何一进入一个activity就弹出输入法键盘

Android软键盘挡住输入框问题的终极解决方案

登录界面软键盘遮挡登入按钮 空间

点击列表后弹出输入框,所点击项自动滚动到输入框上方(类似微信朋友圈的评论)

自定义软键盘输入盖住edittext的问题怎么解决