先上效果图:
当软键盘出来的时候会自动把登录按钮顶上去,显示出来,就不会有遮挡的情况了
前言:
最近好多人在开发中都遇到了登录界面或者其他地方,弹出软键盘的时候遮挡按钮或者输入框的问题,所以在这里集思广益将网上大部分的思路整合一下,贴出来
写了一个Demo演示一下:
正常情况下是这样的,不过软键盘弹出来就变成了:
可以看到将两个按钮遮住了一个半.
正文:
Android虽然提供了WindowSoftInputMode,亲测,效果并不是很好,达不到预期的效果,这里从网上扒了扒主要的实现思路,这里感谢:
http://blog.youkuaiyun.com/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"
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();
}
}
}
}
好的以上内容就是这些了,第一次写博客,有些仓促,如果有什么错误或不妥的地方,欢迎大家评论,我会积极改正...