自定义ViewAndroid知识Android开发

对网上【自定义输入框】的改动

2017-03-17  本文已影响114人  zzEND

开发APP的时候经常会遇到的一个需求就是“自定义一个输入框”,市面上几乎所有app的输入框基本都是他们自己开发的。

自定义布局并非难事,难的是当软键盘弹出时,如何保证你的输入框能自动被顶起。

作为一个新手,遇到问题先百度一下,果然很快就在网上找到了“解决方案”:

 View decorView = getWindow().getDecorView();
 View contentView = mEditText;// 此处的控件ID可以使用界面当中的指定的任意控件
 decorView.getViewTreeObserver().addOnGlobalLayoutListener(getGlobalLayoutListener(decorView, contentView));


private ViewTreeObserver.OnGlobalLayoutListener getGlobalLayoutListener(final View decorView, final View contentView) {
    return 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);
                }
            }
        }
    };
}

这段代码你能很轻易的在网上找到,作用大概是:声明getGlobalLayoutListener()方法,传入你的手机屏幕与指定的控件。ViewTreeObserver会监听你的屏幕,当软键盘弹出时,屏幕可见高度(r.bottom)变小。计算屏幕高度与r.bottom的差值,即为软键盘的高度(diff)。将指定控件的paddingBottom设为diff,就实现了“自定义输入框位于软键盘上方”。同理,当软键盘消失时,paddingBottom设为0,输入框自动落回底部。

这段代码本身没有问题,在绝大多数情况下都可以正常使用。可是根据我的测试,在部分Android4.4的手机上,会出现bug,具体表现为“输入框移动的高度变为软键盘高度的两倍”。

具体原因不明,我初步怀疑是setPadding的的处理机制不同导致的bug。如果padding是从屏幕底部开始计算,则padding值等于软键盘高度是没问题的。可是如果padding是从屏幕可见区域开始计算的,那么此时不需要paddingBottom。

于是我改了一下控件位移的方式,不再使用setPadding。下面是我改动后的代码:

private ViewTreeObserver.OnGlobalLayoutListener getGlobalLayoutListener(final View decorView, final View contentView){
        return new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                Rect r = new Rect();
                decorView.getWindowVisibleDisplayFrame(r);

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

                if (diff != 0) {
                    if (contentView.getPaddingBottom() != diff) {
                        contentView.setY(r.bottom - contentView.getHeight());
                    }
                } else {
                    contentView.setY(decorView.getHeight() - contentView.getHeight());
                }
            }
        };
    }

我这里仅仅是将setPadding改为了setY,直接指定空间的坐标高度,这样适配问题就解决了。注意Y值等于屏幕可见高度(r.bottom)减去控件高度( contentView.getHeight() )

上一篇下一篇

猜你喜欢

热点阅读