小小草图不成敬意;
GIF图是效果,我确保忘记密码按钮也显示出来;
默认情况下,软键盘弹出来时会把登录按钮遮盖住,用户需要点击登录按钮时需要先隐藏软键盘;
使用android:windowSoftInputMode="adjustPan"也只是不让软键盘遮盖输入框,
需要把登录的按钮不被软键盘遮盖,只需要平移登录的Layout就行了;
在软键盘打开时把布局向上移,软键盘关闭时复位;位移的高度就是草图 Y2 - Y1;
可以仅移动登录Layout的布局,也可以移动最外层的rootView布局;
layoutLogin.post(new Runnable() {
@Override
public void run() {
//不可以直接获取控件位置,放在这个里面获取;
int[] viewLocation = new int[2];
layoutLogin.getLocationOnScreen(viewLocation); //获取该控价在屏幕中的位置(左上角的点)
// loginViewtoBottom = UiUtils.getScreenHeight(mContext) - layoutLogin.getBottom(); //getBottom是该控件最底部距离父控件顶部的距离
loginViewtoBottom = UiUtils.getScreenHeight(mContext) - viewLocation[1] - layoutLogin.getHeight(); //屏幕高度-控件距离顶部高度-控件高度
}
});
下面这个时软键盘监听的工具类:
public class KeyBoardHelper {
private Activity activity;
private OnKeyBoardStatusChangeListener onKeyBoardStatusChangeListener;
private int screenHeight;
// 空白高度 = 屏幕高度 - 当前 Activity 的可见区域的高度
// 当 blankHeight 不为 0 即为软键盘高度。
private int blankHeight = 0;
public KeyBoardHelper(Activity activity) {
this.activity = activity;
screenHeight = activity.getResources().getDisplayMetrics().heightPixels;
activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
if (activity.getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
View content = activity.findViewById(android.R.id.content);
content.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
public void onDestory() {
View content = activity.findViewById(android.R.id.content);
content.getViewTreeObserver().removeOnGlobalLayoutListener(onGlobalLayoutListener);
}
private ViewTreeObserver.OnGlobalLayoutListener onGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect rect = new Rect();
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
int newBlankheight = screenHeight - rect.bottom;
if (newBlankheight != blankHeight) {
if(newBlankheight==0){
// keyboard close
if (onKeyBoardStatusChangeListener != null) {
// onKeyBoardStatusChangeListener.OnKeyBoardClose(newBlankheight);
onKeyBoardStatusChangeListener.OnKeyBoardClose(blankHeight);
}
}else{
// keyboard pop
if (onKeyBoardStatusChangeListener != null) {
onKeyBoardStatusChangeListener.OnKeyBoardPop(newBlankheight);
}
}
}
blankHeight = newBlankheight;
}
};
public void setOnKeyBoardStatusChangeListener(
OnKeyBoardStatusChangeListener onKeyBoardStatusChangeListener) {
this.onKeyBoardStatusChangeListener = onKeyBoardStatusChangeListener;
}
public interface OnKeyBoardStatusChangeListener {
void OnKeyBoardPop(int keyBoardheight);
void OnKeyBoardClose(int oldKeyBoardheight);
}
}
软键盘的高度 - 登录Layout距离屏幕底部高度 = 动画位移距离;
KeyBoardHelper keyBoardHelper = new KeyBoardHelper(this);
keyBoardHelper.setOnKeyBoardStatusChangeListener(new KeyBoardHelper.OnKeyBoardStatusChangeListener() {
@Override
public void OnKeyBoardPop(int keyBoardheight) {
L.i(keyBoardheight + "--open");
// rootView.scrollTo(0, keyBoardheight - loginViewtoBottom);
if (animatorUp == null) { //如果每次弹出的键盘高度不一致,就不要这个判断,每次都新创建动画(密码键盘可能和普通键盘高度不一致)
int translationY = keyBoardheight - loginViewtoBottom;
animatorUp = ObjectAnimator.ofFloat(layoutLogin, "translationY", 0, -translationY);
animatorUp.setDuration(360);
animatorUp.setInterpolator(new AccelerateDecelerateInterpolator());
}
animatorUp.start();
}
@Override
public void OnKeyBoardClose(int oldKeyBoardheight) {
L.i(oldKeyBoardheight + "--close");
// rootView.scrollTo(0, 0);
if (animatorDown == null) {//如果每次弹出的键盘高度不一致,就不要这个判断,每次都新创建动画(密码键盘可能和普通键盘高度不一致)
int translationY = oldKeyBoardheight - loginViewtoBottom;
animatorDown = ObjectAnimator.ofFloat(layoutLogin,"translationY",-translationY, 0);
animatorDown.setDuration(360);
animatorDown.setInterpolator(new AccelerateDecelerateInterpolator());
}
animatorDown.start();
}
});
好了大功告成!!!
下面时全部代码,有兴趣的可以看看:
布局文件:
Activity中的initList函数:
private int loginViewtoBottom;
private ObjectAnimator animatorUp,animatorDown;
@Override
protected void initList() {
layoutLogin.post(new Runnable() {
@Override
public void run() {
//不可以直接获取控件位置,放在这个里面获取;
int[] viewLocation = new int[2];
layoutLogin.getLocationOnScreen(viewLocation); //获取该控价在屏幕中的位置(左上角的点)
// loginViewtoBottom = UiUtils.getScreenHeight(mContext) - layoutLogin.getBottom(); //getBottom是该控件最底部距离父控件顶部的距离
loginViewtoBottom = UiUtils.getScreenHeight(mContext) - viewLocation[1] - layoutLogin.getHeight(); //屏幕高度-控件距离顶部高度-控件高度
}
});
KeyBoardHelper keyBoardHelper = new KeyBoardHelper(this);
keyBoardHelper.setOnKeyBoardStatusChangeListener(new KeyBoardHelper.OnKeyBoardStatusChangeListener() {
@Override
public void OnKeyBoardPop(int keyBoardheight) {
L.i(keyBoardheight + "--open");
// rootView.scrollTo(0, keyBoardheight - loginViewtoBottom);
if (animatorUp == null) { //如果每次弹出的键盘高度不一致,就不要这个判断,每次都新创建动画(密码键盘可能和普通键盘高度不一致)
int translationY = keyBoardheight - loginViewtoBottom;
animatorUp = ObjectAnimator.ofFloat(layoutLogin, "translationY", 0, -translationY);
animatorUp.setDuration(360);
animatorUp.setInterpolator(new AccelerateDecelerateInterpolator());
}
animatorUp.start();
}
@Override
public void OnKeyBoardClose(int oldKeyBoardheight) {
L.i(oldKeyBoardheight + "--close");
// rootView.scrollTo(0, 0);
if (animatorDown == null) {//如果每次弹出的键盘高度不一致,就不要这个判断,每次都新创建动画(密码键盘可能和普通键盘高度不一致)
int translationY = oldKeyBoardheight - loginViewtoBottom;
animatorDown = ObjectAnimator.ofFloat(layoutLogin,"translationY",-translationY, 0);
animatorDown.setDuration(360);
animatorDown.setInterpolator(new AccelerateDecelerateInterpolator());
}
animatorDown.start();
}
});
}
涉及到的一些工具类(获取屏幕高度)可以自己实现;