zoukankan      html  css  js  c++  java
  • 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) {
              /**低版本的 android:windowSoftInputMode="adjustResize" 无法生效,软键盘弹出时布局会被破坏。直接返回即可**/
              if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M){
             return;
              }
    /**获取当前点击的控件**/
                    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被软键盘遮挡

  • 相关阅读:
    Mac下PyCharm快捷键大全
    SQL语句优化
    There was a problem confirming the ssl certificate: [SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version (_ssl.c:661)
    Hadoop Trash回收站使用指南
    HDFS 中向 DataNode 写入数据失败了怎么办
    mapreduce 实现写出orc文件
    mapreduce读取压缩文件
    hive开窗函数over(partition by ......)用法
    Mac 安装 home Brew以及 XCTool的过程记录
    iOS开发中使用CocoaPods来管理第三方的依赖程序
  • 原文地址:https://www.cnblogs.com/ice5/p/13907961.html
Copyright © 2011-2022 走看看