最近忙于自媒体事业不能自拔,已经很久没有写技术博客了。之所以写是因为这个非常的重要,也非常的好用。先上一张完美的效果图。

 //监听键盘展开 、收起    private void listenerKeyBoard() {        getWindow().getDecorView().addOnLayoutChangeListener(new View.OnLayoutChangeListener() {            @Override            public void onLayoutChange(View v, int left, int top, int right,                                       int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {                //当页面布局发生变化的时候调用                YetuLog.e("onLayoutChange", "onLayoutChange: " + "调用");                //因为addOnGlobalLayoutListener是在页面加载完成后才调用,所以当前获取的View参数都是真实有效                int[] location = new int[2];                rlMiddle.getLocationOnScreen(location);                rl_height = location[1];                setViewHeight();            }        });    }    private boolean isSoftShowing() {        //获取当前屏幕内容的高度        int screenHeight = getWindow().getDecorView().getHeight();        //获取View可见区域的bottom        Rect rect = new Rect();        getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);        return screenHeight - rect.bottom != 0;    }    private void setViewHeight() {//        YetuLog.e("onLayoutChange", "onLayoutChange: " + rl_height);        if (isSoftShowing()) {            //软键盘弹出//            YetuLog.e("onLayoutChange", "onLayoutChange: " + "弹出");            //rl_height==0 页面已经上移,不再向上移动(这里是对非软键盘导致的布局切换变化做一个判断)            if (rl_height != 0) {                ObjectAnimator translationY = new ObjectAnimator().ofFloat(rlMiddle, "translationY", 0, -layTop.getBottom());                //在这里0表示当前控件的位置                translationY.setDuration(200);                translationY.start();            }        } else {            //软键盘收起//            YetuLog.e("onLayoutChange", "onLayoutChange: " + "收起");            if (rl_height == 0) {                ObjectAnimator translationY = new ObjectAnimator().ofFloat(rlMiddle, "translationY", -layTop.getBottom(), 0);                translationY.setDuration(200);                translationY.start();            }        }    }    @Override    protected void onResume() {        super.onResume();        //addOnGlobalLayoutListener 判断页面是否已经加载完毕        getWindow().getDecorView().getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {            /**             * Callback method to be invoked when the global layout state or the visibility of views             * within the view tree changes             */            @Override            public void onGlobalLayout() {                //判断是否第一次进入页面                if (!isLoaded) {                    isLoaded = true;                    listenerKeyBoard();                }else{                    int[] location = new int[2];                    rlMiddle.getLocationOnScreen(location);                    rl_height = location[1];//                    YetuLog.e("onLayoutChange", "onLayoutChange: " + "重新初始化" + rl_height);                    setViewHeight();                }                getWindow().getDecorView().getViewTreeObserver().removeOnGlobalLayoutListener(this);            }        });    }

大概讲一下逻辑吧。首先是执行onResume方法里的代码,这里面isLoaded是一个标记,只有在第一次进入该页面的时候,才会调用listenerKeyBoard方法,启动onLayoutChange监听。else的情况是在进入下一个页面,然后再返回有编辑框的时候,直接调用判断软键盘状态的方法setViewHeight()同时设置页面动画。这其中,lay_top是那个带有返回键的控件,rlMiddle这是那整块在移动的控件。调用addOnGlobalLayoutListener是为了确认布局已经加载完成,这样才能准确的获取控件宽高之类的参数。其中,判断软键盘状态的核心方法是isSoftShowing()。剩下的代码注释都有,布局文件就不贴出来了。

上图是附录测试log。该套方法主要用于,在页面没有ScrollView或者RecyclerView之类的列表或者EditView太高,而其他的控件又太低,没办法把底下的这些控件顶起来,只能手动移动控件的时候。之所以使用属性动画,没有直接onlayout(),是考虑到整个布局的平滑过渡,使用属性动画的体验会更好些。

更多相关文章

  1. android 在xml中指定按钮点击事件
  2. Android踩坑日记:FloatingActionButton的设置大小问题
  3. Android(安卓)UI 问题随笔
  4. android常见错误之Nor…
  5. android中fragment在后台回收时的生命周期
  6. [Accessibility] Missing contentDescription attribute on imag
  7. Android百度地图之页面跳转
  8. ExpandableListView的使用
  9. 随笔--android中修改SeekBar控件默认显示

随机推荐

  1. 自学系列 | 就谈知识体系!
  2. Python异步爬虫进阶必备,效率杠杠的!
  3. Ansible 之 外部变量文件调用
  4. JavaScript的工作原理:引擎、运行时和调用
  5. 图解「剑指Offer」之二维数组中的查找
  6. 超简单的博弈算法题,一行代码解决!
  7. 超经典MySQL练习50题,做完这些你的SQL就过
  8. 三分钟理解字符串经典考题:有效的字母异位
  9. 动画:面试必刷之二叉树中和为某一值的路径
  10. 使用位运算处理一道难题:获取所有钥匙的最