键盘遮挡输入框bug

今天解决了一个bug,虚拟键盘遮挡输入框。
 

解决这类问题有多种做法,但是也针对不同的项目情况做法也不同

出现的问题像在底部的输入框,当键盘弹出后输入框被遮住

解决思路有几种,需要有几点需要注意,稍后做一下解释,也是参考了好多网络资料再此表示感谢

1.一种时常见的简单直接在manifest中设置windowSoftInputModel="adjustPan|stateHidden"

这种在布局中用Scorllview套住即可。当然根据不通的主题设置有各种不同的注意点,网上有说ScrollView中fillViewPort=true的,有说fitSystemWindow=true的情况。下面是我的情况使用的。综合给大家些意见。

 

2.一种是,整个activity顶起,达到不被遮住的目的

public class AndroidBug5497Workaround {

    // For more information, see https://code.google.com/p/android/issues/detail?id=5497
    // To use this class, simply invoke assistActivity() on an Activity that already has its content view set.

    public static void assistActivity (Activity activity) {
        new AndroidBug5497Workaround(activity);
    }

    private View mChildOfContent;
    private int usableHeightPrevious;
    private FrameLayout.LayoutParams frameLayoutParams;

    private AndroidBug5497Workaround(Activity activity) {
        FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
        mChildOfContent = content.getChildAt(0);
        mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            public void onGlobalLayout() {
                possiblyResizeChildOfContent();
            }
        });
        frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
    }

    private void possiblyResizeChildOfContent() {
        int usableHeightNow = computeUsableHeight();
        if (usableHeightNow != usableHeightPrevious) {
            int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
            int heightDifference = usableHeightSansKeyboard - usableHeightNow;
            if (heightDifference > (usableHeightSansKeyboard/4)) {
                // keyboard probably just became visible
                frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
            } else {
                // keyboard probably just became hidden
                frameLayoutParams.height = usableHeightSansKeyboard;
            }
            mChildOfContent.requestLayout();
            usableHeightPrevious = usableHeightNow;
        }
    }

    private int computeUsableHeight() {
        Rect r = new Rect();
        mChildOfContent.getWindowVisibleDisplayFrame(r);
        return (r.bottom - r.top);// 全屏模式下: return r.bottom
    }

}

这种是把整个activity上移达到不被遮挡,看代码知道是把activity的setContentView做处理

这种情况很方便,但是我改的别人bug使用无效,情况是项目主题设置了背景透明,这里这种方法有bug就是,当虚拟键盘弹出后,关闭键盘这时就会出现背景透明。如果没有设置主题背景透明这种情况是没有问题的也挺方便。

3.第二种就设置布局的padding值代码如下,当键盘谈起时把底部垫高,也算适合我这种情况,但是如果又在activity中设置全屏模式,我提到的所有情况都无效。
 

public class KeyboardPatch {
    private Activity activity;
    private View decorView;
    private View contentView;

    /**
     * 构造函数
     * @param act 需要解决bug的activity
     * @param contentView 界面容器,activity中一般是R.id.content,也可能是Fragment的容器,根据个人需要传递
     * */
    public KeyboardPatch(Activity act, View contentView)
    {
        this.activity = act;
        this.decorView = act.getWindow().getDecorView();
        this.contentView = contentView;
    }

    /**
     * 监听layout变化
     * */
    public void enable()
    {
        activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
        if (Build.VERSION.SDK_INT >= 19)
        {
            decorView.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
        }
    }

    /**
     * 取消监听
     * */
    public void disable()
    {
        activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
        if (Build.VERSION.SDK_INT >= 19)
        {
            decorView.getViewTreeObserver().removeOnGlobalLayoutListener(onGlobalLayoutListener);
        }
    }

    private ViewTreeObserver.OnGlobalLayoutListener onGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener()
    {
        @Override
        public void onGlobalLayout()
        {
            Rect r = new Rect();

            decorView.getWindowVisibleDisplayFrame(r);
            int height = decorView.getContext().getResources().getDisplayMetrics().heightPixels;
            int diff = height - r.bottom;

            if (diff != 0)
            {
                if (contentView.getPaddingBottom() != diff)
                {
                    contentView.setPadding(0, 0, 0, diff);
                }
            }
            else
            {
                if (contentView.getPaddingBottom() != 0)
                {
                    contentView.setPadding(0, 0, 0, 0);
                }
            }
        }
    };
}

 这种可以根据你的情况设置contentview,看代码就是,虚拟键盘弹出时设置padding值垫高,关闭时padding值为零。

如果大家有想法欢迎给点意见

猜你喜欢

转载自blog.csdn.net/chengzuidongfeng/article/details/85342733