android软键盘弹出时如何处理页面布局

Posted 程序猿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android软键盘弹出时如何处理页面布局相关的知识,希望对你有一定的参考价值。

android里软键盘弹出顶起当前布局是常见的问题。

首先了解下软键盘和activity的几个交互模式(windowSoftInputMode)

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

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

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

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

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

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

【G】adjustUnspecified:默认设置,通常由系统自行决定是隐藏还是显示。使用该设置,软键盘弹出,页面里的图片可能会有影响。

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

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

网上常见的解决问题的方案是将 windowSoftInputMode 的值设置为

android:windowSoftInputMode="adjustResize|stateHidden"

或者

android:windowSoftInputMode="adjustPan|stateHidden"

但是,当页面比较复杂时,软键盘依然会破坏当前布局,或遮挡输入框。

下面从配置到代码梳理下解决方案。

本例中,一个页面包含10+各edittext,都是通过代码动态添加的

1,设置AndroidManifest.xml里的windowSoftInputMode

<activity
            android:name=".view.PostActivity"
            android:configChanges="keyboardHidden"
            android:windowSoftInputMode="adjustResize|stateHidden" />

2,软键盘监听

public class KeyboardListener {
    final String TAG=this.getClass().getName();

    private View rootView; // activity的根视图
    int rootViewVisibleHeight; // 记录根视图显示的高度
    private OnKeyBoardDisplayListener onKeyBoardDisplayListener;

    public KeyboardListener(Activity activity){
        // 获取activity的根视图
        rootView = activity.getWindow().getDecorView();
        // 监听视图树中全局布局发生改变或者视图树中某个视图的可视状态发生改变
        rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                // 获取当前根视图在屏幕上显示的大小
                Rect rect = new Rect();
                rootView.getWindowVisibleDisplayFrame(rect);
                int visibleHeight = rect.height();
                if(rootViewVisibleHeight == 0){
                    rootViewVisibleHeight = visibleHeight;
                    return;
                }

                //根视图显示高度没有变化,可以看做软键盘显示/隐藏状态没有变化
                if(rootViewVisibleHeight == visibleHeight){
                    return;
                }

                // 根视图显示高度变小超过200,可以看做软键盘显示了
                if(rootViewVisibleHeight -visibleHeight > 200){
                    if(onKeyBoardDisplayListener !=null){
                        onKeyBoardDisplayListener.keyBoardShow(rootViewVisibleHeight - visibleHeight);
                    }
                    rootViewVisibleHeight = visibleHeight;
                    return;
                }

                // 根视图显示高度变大超过了200,可以看做软键盘隐藏了
                if(visibleHeight - rootViewVisibleHeight > 200){
                    if(onKeyBoardDisplayListener != null){
                        onKeyBoardDisplayListener.keyBoardHide(visibleHeight - rootViewVisibleHeight);
                    }
                    rootViewVisibleHeight = visibleHeight;
                    return;
                }
            }
        });

    }

    public interface OnKeyBoardDisplayListener{
        void keyBoardShow(int height);
        void keyBoardHide(int height);
    }

    public void setOnSoftKeyBoardChangeListener(OnKeyBoardDisplayListener onKeyBoardDisplayListener) {
        this.onKeyBoardDisplayListener = onKeyBoardDisplayListener;
    }
}

3,activity添加对软键盘的监听

在activity的onCreate添加

KeyboardListener softKeyboardListener = new KeyboardListener(this);
        softKeyboardListener.setOnSoftKeyBoardChangeListener(new KeyboardListener.OnKeyBoardDisplayListener() {
            @Override
            public void keyBoardShow(final int height) {
                /**获取当前点击的控件**/
                View view=getWindow().getDecorView().findFocus();/**获取坐标。location[0] 为 x,1为y**/
                int[] location = new  int[2] ;
                view.getLocationInWindow(location);
                ScrollView scrollView=getView(R.id.scroll_view);int scroll_y_distance=height-(ScreenUtil.getScreenHeightPx(PostActivity.this)-location[1]);
                scrollView.setPadding(0,0,0,scroll_y_distance);
                scrollView.scrollTo(0,scroll_y_distance);
            }

            @Override
            public void keyBoardHide(int height) {
                ScrollView scrollView=getView(R.id.scroll_view);
                scrollView.setPadding(0,0,0,0);
            }
        });

4,xml文件

所有的内容通过java代码追加到 content_container 里

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    style="@style/Match2">
    <ScrollView
        android:id="@+id/scroll_view"
        style="@style/Match2" android:scrollbars="none">
      <LinearLayout
          android:id="@+id/content_container"
          style="@style/content_container">
      </LinearLayout>
    </ScrollView>
</FrameLayout>

到这里基本上就能正常显示软键盘,不会破坏页面布局,也不会担心edittext被软键盘遮挡

以上是关于android软键盘弹出时如何处理页面布局的主要内容,如果未能解决你的问题,请参考以下文章

Android 软键盘弹出时布局内指定内容上移实现及问题解决

Android 软键盘弹出时布局内指定内容上移实现及问题解决

怎么让软键盘弹出时,部分控件上移

DialogActivity软键盘弹出时布局顶上去的问题

DialogActivity软键盘弹出时布局顶上去的问题

Android软键盘弹出时,防止底部Tab按钮被挤上去