android 监听软键盘弹出和隐藏和4.4系统沉浸式通知栏冲突解决

来源:互联网 发布:淘宝微信福利群可信吗 编辑:程序博客网 时间:2024/05/16 14:44

由于项目的需要相信大家肯定会遇到各种各样的问题,如何去解决问题,如何去学习进步,对我们来说都很重要。希望自己能养成记录的习惯,也希望自己遇到的问题能帮助更多的人少走弯路。
在这里我们首先说一下android监听软键盘弹出的实现方法。这样的方法相信网上也有很多。在这里我介绍一下我项目所用的吧。
1 。监听软键盘的弹出和隐藏。
由于google没有提供监听的方法,好多项目需求都会需要这样的监听,那就需要我们去自己实现了。
首先键盘弹出的时候会造成Activity的布局大小会被压缩上去,但是你仍然可以通过滑动浏览所有。这里我们想到的就是监听这个页面的跟布局。通过Layout方法,通过监听 Bottom position, 也就是参与b的大小来监听键盘是否弹出。一般来说小于屏幕高度的三分之二的时候就是键盘弹出,反之就是隐藏。然后通过接口的回调在相应的类里面做好自己的操作。直接上代码。

package com.waterh2.qyh.widget.view;import com.waterh2.qyh.util.QYHUtils;import android.content.Context;import android.util.AttributeSet;import android.widget.LinearLayout;public class KeyboardListenerLinearLayout extends LinearLayout {    private Context context;    private KeyboardListener keyboardListener;    private boolean isKeyBoardShowing = false;    public KeyboardListenerLinearLayout(Context context, AttributeSet attrs) {        super(context, attrs);        this.context = context;    }    public KeyboardListenerLinearLayout(Context context) {        super(context);        this.context = context;    }    protected void onLayout(boolean changed, int l, int t, int r, int b) {        if (b < QYHUtils.getScreenHeight(context) * 2 / 3) {            if (keyboardListener != null) {                keyboardListener.onKeyBoardShow();                isKeyBoardShowing = true;            }        } else {            if (keyboardListener != null) {                keyboardListener.onKeyBoardHide();                isKeyBoardShowing = false;            }        }        super.onLayout(changed, l, t, r, b);    }    public boolean isKeyBoardShowing() {        return isKeyBoardShowing;    }    public KeyboardListener getKeyboardListener() {        return keyboardListener;    }    public void setKeyboardListener(KeyboardListener keyboardListener) {        this.keyboardListener = keyboardListener;    }    public interface KeyboardListener {        void onKeyBoardHide();        void onKeyBoardShow();    }}

还有 就是activity的android:windowSoftInputMode属性。在这里我就不详细介绍了,大家可以看这篇文章,作者分析的很详细。
http://blog.csdn.net/zhaoyw2008/article/details/40622919
大家可以写一个小的demo,各种属性都试一下,直观的效果可能印象更深刻。
关于监听软键盘弹出还有一种方式,原理是一样的。是我的同事想的一种方案。就是重写一个view.在布局中把这个view放在跟布局的最下面,颜色设置为透明。当键盘弹出的时候把这个view会往上顶,从而重新绘制这个view.他的流程是先进行measure,然后进行Layout,最后进行draw的方法,绘制在屏幕上。直接上代码吧

package com.dfhe.ui.widget;import android.content.Context;import android.graphics.Canvas;import android.graphics.Rect;import android.util.AttributeSet;import android.util.Log;import android.widget.ImageView;import com.dfhe.util.DfheUtils;/** * Created by xll on 2015/12/11. */    public class KeyBoardListenerLayout extends ImageView    {        Context context;        public KeyBoardListenerLayout(Context context)        {            super(context);            this.context=context;            // TODO Auto-generated constructor stub        }        public KeyBoardListenerLayout(Context context, AttributeSet attrs, int defStyleAttr) {            super(context, attrs, defStyleAttr);            this.context=context;        }        public KeyBoardListenerLayout(Context context, AttributeSet attrs) {            super(context, attrs);            this.context=context;        }        public  interface ImeUiChangeListener        {            public void onImeUiChange(int bottom);        }        public interface KeyBoardListener{            public void keyBoardShow();            public void keyBoardHide();        }        private KeyBoardListener mKeyBoardListener;        public void setKeyBoardListener(KeyBoardListener keyBoardListener) {            mKeyBoardListener = keyBoardListener;        }        private int mPreBottom = 0;        @Override        protected void onDraw(Canvas canvas)        {            super.onDraw(canvas);            Rect r = new Rect();            if(getGlobalVisibleRect(r))            {                //键盘隐藏的回调   测量出屏幕的高度 单位是px             这个是dp转换成px的方法。超过80dp则为一个键盘高度                                    if(r.bottom> (DfheUtils.getScreenHeight(context)-DfheUtils.dipToPixels(context,80)))                {                    if(mKeyBoardListener!=null)                        mKeyBoardListener.keyBoardHide();                    mPreBottom = r.bottom;                }else{                    if(mKeyBoardListener!=null)                        mKeyBoardListener.keyBoardShow();                }            }        }}

个人觉得第二个方法比较容易扩展,可以随便放在布局中。那么无论那种方法都是基于屏幕会被压缩,咱们的布局会被重构的前提下的。那么当android4.4系统以后。问题来了。你用这些方法根本不会起到任何作用。你自定义的控件相对于底部距离根本没有变化。经过多方的查询资料,翻开各大网站的文章终于找到了原因,因为我用了Android 沉浸式状态栏。解决起来很简单就是把你页面的跟布局fitSystemWindows设置为true. 及android:fitsSystemWindows=”true”就可以解决上面自定义布局没有重构的问题。

fitSystemWindows属性:
官方描述:

    Boolean internal attribute to adjust view layout based on system windows such as the status bar. If true, adjusts the padding of this view to leave space for the system windows. Will only take effect if this view is in a non-embedded activity.简单描述: 这个一个boolean值的内部属性,**让view可以根据系统窗口(如status bar)来调整自己的布局**,如果值为true,就会调整view的paingding属性来给system windows留出空间....

这就是我们所遇到问题的根本是因为我们的布局没有去跳转所以那些bottom也就没有变化。键盘弹出隐藏事件终于可以监听了,好了那么问题又来了,我们在4.4的系统通知栏会变的很丑。通知栏上面会消失。你的title会变的很高,由于图片太丑就不上传了。
大家不要急,这里有两种解决方法,一种就是移动你的跟布局。在加载页面的时候把你的跟布局向上移动状态栏通知的高度。这里我发现不太好搞适配。第二种方式就是换一种通知栏的方式。那就是用开源的SystemBarTint使用。这里网上有很多资料。这里是我上传的SystemBarTint的jar包。
http://download.csdn.net/detail/u014007519/9477461
至于使用的方法大家可以去网上找。很简单的。

1 2
原创粉丝点击