Android开发软键盘遮挡问题汇总

来源:互联网 发布:送别领导的诗句 知乎 编辑:程序博客网 时间:2024/05/17 05:01

先上效果图:

当软键盘出来的时候会自动把登录按钮顶上去,显示出来,就不会有遮挡的情况了



前言:

最近好多人在开发中都遇到了登录界面或者其他地方,弹出软键盘的时候遮挡按钮或者输入框的问题,所以在这里集思广益将网上大部分的思路整合一下,贴出来

写了一个Demo演示一下:


正常情况下是这样的,不过软键盘弹出来就变成了:




可以看到将两个按钮遮住了一个半.




正文:

Android虽然提供了WindowSoftInputMode,亲测,效果并不是很好,达不到预期的效果,这里从网上扒了扒主要的实现思路,这里感谢:
http://blog.csdn.net/nn955/article/details/17717749


开始了,主要有两种思路:


1.通过窗体的根View求出总的区域和可视区域就可以计算出被遮挡的区域的高度,如果超过一定的值就是软键盘弹出了,然后将根View ScrollTo到一个位置

2.自定义根View,集成(FrameLayout,LinearLayout,RelativeLayout需要什么集成什么),当软键盘弹出的时候肯定会走onSizeChange方法,这里重写onSizeChange方法,在里面做我们的逻辑即可

只要判断出了软键盘弹出之后,思路就很开阔了,可以根据自己的情况选择怎么实现,这里提供几种常用的思路:
(1) 移动到指定的位置,不让软键盘遮挡
(2) 改变布局的PaddingTop,网上移动一段距离,让遮挡的部分显示出来
(3) 改变某一个View的高度,让其他显示出来
(4) 隐藏某一个View,让其他的显示出来
........................

贴出代码:

<?xml version="1.0" encoding="utf-8"?><com.example.justin.takephotodemo.MyLinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/layout"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    android:padding="10dp"    tools:context="com.example.justin.takephotodemo.MainActivity">    <ImageView        android:id="@+id/iv"        android:layout_width="match_parent"        android:layout_height="200dp"        android:background="@drawable/csdn"        android:layout_marginBottom="10dp"        />    <android.support.design.widget.TextInputLayout        android:layout_width="match_parent"        android:layout_height="wrap_content">        <EditText            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:hint="请输入用户名"/>    </android.support.design.widget.TextInputLayout>    <android.support.design.widget.TextInputLayout        android:layout_width="match_parent"        android:layout_height="wrap_content">        <EditText            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:hint="请输入密码"/>    </android.support.design.widget.TextInputLayout>    <Button        android:id="@+id/register"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:onClick="select"        android:text="注册"/>    <Button        android:id="@+id/login"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="登录"/></com.example.justin.takephotodemo.MyLinearLayout>

第一种思路的实现:





通过图可以看出,得到总的高度,和获取可见区域的高度就可以算出被隐藏的高度,通过比较即可判断是否是软键盘弹出了
计算RootView要移动的距离,需要知道被移动View的坐标,通过坐标的高度加上本身View的高度,减去可见区域的bottom就是要移动的距离
好吧,图画的有点抽象,........................

在onCreate中:
        mLayout = (LinearLayout) findViewById(R.id.layout);        mIv = (ImageView) findViewById(R.id.iv);        Button mLogin = (Button) findViewById(R.id.login);        autoScrollView(mLayout,mLogin);

    /**这里判断出软键盘弹出,之后的逻辑可以自己定,1.隐藏 2.移动3.改变高度4.改变paddingTop.......都可以
     * @param root 最外层的View     * @param scrollToView 不想被遮挡的View,会移动到这个Veiw的可见位置     */    private void autoScrollView(final View root, final View scrollToView) {        root.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {            @Override            public void onGlobalLayout() {                Rect rect = new Rect();                //获取root在窗体的可视区域                root.getWindowVisibleDisplayFrame(rect);                //获取root在窗体的不可视区域高度(被遮挡的高度)                int rootInvisibleHeight = root.getRootView().getHeight() - rect.bottom;                //若不可视区域高度大于150,则键盘显示                if (rootInvisibleHeight > 150) {                    int[] location = new int[2];                    //获取scrollToView在窗体的坐标                    scrollToView.getLocationInWindow(location);                    //计算root滚动高度,使scrollToView在可见区域的底部                    int srollHeight = (location[1] + scrollToView.getHeight()) - rect.bottom;                    root.scrollTo(0, srollHeight);                } else {                    //键盘隐藏                    root.scrollTo(0, 0);                }            }        });    }


第二种实现方式:


注意:需要在AndroidManifest中加上
android:windowSoftInputMode="adjustResize"

自定义layout
public class MyLinearLayout extends LinearLayout {    public MyLinearLayout(Context context) {        super(context);    }    public MyLinearLayout(Context context, AttributeSet attrs) {        super(context, attrs);    }    public MyLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        if (oldh > 0) {            int screenHeight = this.getRootView().getHeight();            if (oldh - h >= screenHeight / 3) {//弹出 (之后的逻辑可以自己定,1.隐藏 2.移动3.高度4.paddingTop.......)                Toast.makeText(getContext(), "弹出", Toast.LENGTH_SHORT).show();            } else {//隐藏                Toast.makeText(getContext(), "隐藏", Toast.LENGTH_SHORT).show();            }        }    }}

好的以上内容就是这些了,第一次写博客,有些仓促,如果有什么错误或不妥的地方,欢迎大家评论,我会积极改正...





1 0
原创粉丝点击