zoukankan      html  css  js  c++  java
  • 软键盘 显示隐藏 测量高度 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱
    MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina.com

    目录

    软键盘相关问题

    我们在开发中经常会遇到软键盘遮挡住了输入框,而直接把输入框往上顶adjustResize这种方法过于暴力影响美观,我们希望键盘弹出时动态的去改变布局。这时候,便用到了监听键盘弹起事件的功能。

    可能大家都会潜意识觉得:Android中没有可以复写的方法么?或者说,没有什么listener可以让我们使用么?

    抱歉,真的没有,我们潜意识都是以为系统会提供,其实系统提供的是InputMethodManager,让我们控制键盘的弹出和隐藏,而不是键盘弹出和隐藏触发事件。

    Android系统并没有给我们提供监听键盘弹出的方法,同样,Android系统也没有给我们提供获取软键盘的高度的方法,我们只能自己监听view的高度变化来间接判断键盘是不是弹出了,并通过计算获取软键盘的高度。

    目前通用的方法是,由于键盘弹起与隐藏,会使得layout的布局发生变化,通过布局的大小变化触发的事件实现键盘事件的触发。

    设置 OnLayoutChangeListener - 推荐

    不要忘了设置键盘

    android:windowSoftInputMode="stateAlwaysHidden|adjustResize"

    使用

    public class MainActivity extends Activity {
    
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.edit);
    
            int scrollHeight = getWindowManager().getDefaultDisplay().getHeight() / 4;
            findViewById(android.R.id.content).addOnLayoutChangeListener((v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
                if (oldBottom != 0 && bottom != 0) {
                    int softInputHeight = oldBottom - bottom;//这个就是键盘高度
                    Log.i("bqt", "【键盘高度】" + Math.abs(softInputHeight));
    
                    if (softInputHeight > scrollHeight) {
                        Toast.makeText(MainActivity.this, "键盘弹起", Toast.LENGTH_SHORT).show();
                    } else if (Math.abs(softInputHeight) > scrollHeight) {
                        Toast.makeText(MainActivity.this, "键盘落下", Toast.LENGTH_SHORT).show();
                    }
                }
            });
        }
    }

    设置 OnGlobalLayoutListener - 推荐

    不要忘了设置键盘

    android:windowSoftInputMode="stateAlwaysHidden|adjustResize"

    使用

    public class MainActivity extends Activity {
        private int keyboardHeight;
    
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.edit);
    
            new KeyboardChangeListener(this).setKeyBoardListener((isShow, keyboardCurrentHeight) -> {
                Log.i("bqt", "【当前键盘的高度】" + keyboardCurrentHeight);//注意,这里返回的直接是键盘的高度,键盘隐藏时高度为0
                if (isShow) {
                    this.keyboardHeight = keyboardCurrentHeight;
                    Log.i("bqt", "【键盘的高度】" + keyboardHeight);
                    Toast.makeText(MainActivity.this, "键盘弹起", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(MainActivity.this, "键盘隐藏", Toast.LENGTH_SHORT).show();
                }
            });
        }
    }

    KeyboardChangeListener

    public class KeyboardChangeListener implements ViewTreeObserver.OnGlobalLayoutListener {
        private static final String TAG = "bqt";
        private View mContentView;
        private int mOriginHeight;
        private int mPreHeight;
        private KeyBoardListener mKeyBoardListen;
    
        public interface KeyBoardListener {
            /**
             * call back
             *
             * @param isShow         true is show else hidden
             * @param keyboardHeight keyboard height
             */
            void onKeyboardChange(boolean isShow, int keyboardHeight);
        }
    
        public void setKeyBoardListener(KeyBoardListener keyBoardListen) {
            this.mKeyBoardListen = keyBoardListen;
        }
    
        public KeyboardChangeListener(Activity contextObj) {
            if (contextObj == null) {
                Log.i(TAG, "contextObj is null");
                return;
            }
            mContentView = findContentView(contextObj);
            if (mContentView != null) {
                addContentTreeObserver();
            }
        }
    
        private View findContentView(Activity contextObj) {
            return contextObj.findViewById(android.R.id.content);
        }
    
        private void addContentTreeObserver() {
            mContentView.getViewTreeObserver().addOnGlobalLayoutListener(this);
        }
    
        @Override
        public void onGlobalLayout() {
            int currHeight = mContentView.getHeight();
            if (currHeight == 0) {
                Log.i(TAG, "currHeight is 0");
                return;
            }
            boolean hasChange = false;
            if (mPreHeight == 0) {
                mPreHeight = currHeight;
                mOriginHeight = currHeight;
            } else {
                if (mPreHeight != currHeight) {
                    hasChange = true;
                    mPreHeight = currHeight;
                } else {
                    hasChange = false;
                }
            }
            if (hasChange) {
                boolean isShow;
                int keyboardHeight = 0;
                if (mOriginHeight == currHeight) {
                    //hidden
                    isShow = false;
                } else {
                    //show
                    keyboardHeight = mOriginHeight - currHeight;
                    isShow = true;
                }
    
                if (mKeyBoardListen != null) {
                    mKeyBoardListen.onKeyboardChange(isShow, keyboardHeight);
                }
            }
        }
    
        @SuppressLint("ObsoleteSdkInt")
        public void destroy() {
            if (mContentView != null) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                    mContentView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                }
            }
        }
    }

    重写 onSizeChanged - 麻烦,不推荐

    不要忘了设置键盘

    android:windowSoftInputMode="stateAlwaysHidden|adjustResize"

    使用

    public class MainActivity extends Activity {
    
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.edit);
    
            AdjustSizeRelativeLayout layout = findViewById(R.id.rl_root);
            layout.setSoftKeyBoardListener(new AdjustSizeRelativeLayout.SoftkeyBoardListener() {
                @Override
                public void keyBoardVisable(int move) {
                    Toast.makeText(MainActivity.this, "键盘弹起,高度:" + move, Toast.LENGTH_SHORT).show();
                }
    
                @Override
                public void keyBoardInvisable(int move) {
                    Toast.makeText(MainActivity.this, "键盘隐藏,高度:" + move, Toast.LENGTH_SHORT).show();
                }
            });
        }
    }

    布局

    <?xml version="1.0" encoding="utf-8"?>
    <com.bqt.test.AdjustSizeRelativeLayout 
         xmlns:android="http://schemas.android.com/apk/res/android"
         android:id="@+id/rl_root"
         android:layout_width="match_parent"
         android:layout_height="match_parent">
    
        <EditText
            android:layout_width="match_parent"
            android:layout_height="44dp"
            android:layout_alignParentBottom="true"
            android:hint="输入交易密码"
            android:inputType="text"
            android:paddingLeft="5dp"/>
    
    </com.bqt.test.AdjustSizeRelativeLayout>

    自定义的ViewGroup

    public class AdjustSizeRelativeLayout extends RelativeLayout {
        public AdjustSizeRelativeLayout(Context context) {
            super(context);
        }
    
        public AdjustSizeRelativeLayout(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        public AdjustSizeRelativeLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        private static final int CHANGE_SIZE = 200;
    
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            Log.i("bqt", "【onSizeChanged】" + w + " " + h + " " + oldw + " " + oldh);
            if (oldw == 0 || oldh == 0) return;
    
            if (boardListener != null) {
                if (h - oldh < -CHANGE_SIZE) {
                    Log.i("bqt", "键盘弹出" + "change" + w + " " + h + " " + oldw + " " + oldh);
                    boardListener.keyBoardVisable(Math.abs(h - oldh));
                }
                if (h - oldh > CHANGE_SIZE) {
                    Log.i("bqt", "键盘结束" + "change" + w + " " + h + " " + oldw + " " + oldh);
                    boardListener.keyBoardInvisable(Math.abs(h - oldh));
                }
            }
        }
    
        public interface SoftkeyBoardListener {
            public void keyBoardVisable(int move);
    
            public void keyBoardInvisable(int move);
        }
    
        private SoftkeyBoardListener boardListener;
    
        public void setSoftKeyBoardListener(SoftkeyBoardListener boardListener) {
            this.boardListener = boardListener;
        }
    }

    2018-5-21

  • 相关阅读:
    vue-cli项目打包出现空白页和路径错误问题
    Git操作手册
    Atom Editor 插件 atom-less 的使用方法
    Vue搭建
    使绝对定位高宽自适应
    原生JS表单序列化
    前端代码有关搜索引擎的代码
    网页局部打印
    万维网
    浅淡传统企业进入移动互联网的几种方式
  • 原文地址:https://www.cnblogs.com/baiqiantao/p/813bd984967ff66ce1cf10d2eb0cc82d.html
Copyright © 2011-2022 走看看