键盘弹起效果
诉求:需要监听软键盘弹起,并根据键盘高度变化来调整卡片高度
现状:安卓目前并没有官方监听软键盘弹起以及弹起高度的API
功能设计:
- 给页面窗口添加一个高度为屏幕高度,宽度为0的PopupWindow,实现OnGlobalLayoutListener 接口监听键盘是否弹起且返回弹起高度
- 禁止内容输入区域EditText获取焦点自动拉起键盘,外层做点击监听,自己拉起键盘
public class KeyBoardHeightListenerView extends PopupWindow implements ViewTreeObserver.OnGlobalLayoutListener {
private final static String TAG = "KeyBoardHeightListenerView";
private Activity mActivity;
private View rootView;
private HeightListener listener;
private int heightMax; // 记录popup内容区的最大高度
private Rect rect;
private int preKeyboardHeight = 0;
private int statusBarHeight;
private int deviceHeight;
private boolean isIntercept = true;
public KeyBoardHeightListenerView(Activity activity) {
super(activity);
this.mActivity = activity;
try {
// 基础配置
rootView = new View(activity);
setContentView(rootView);
// 监听全局Layout变化
rootView.getViewTreeObserver().addOnGlobalLayoutListener(this);
setBackgroundDrawable(new ColorDrawable(0));
// 设置宽度为0,高度为全屏
setWidth(0);
setHeight(WindowManager.LayoutParams.MATCH_PARENT);
// 设置键盘弹出方式
setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
int resourceId = mActivity.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
statusBarHeight = mActivity.getResources().getDimensionPixelSize(resourceId);
AliUserLog.i(TAG, "statusBarHeight = " + statusBarHeight);
}
deviceHeight = DeviceInfo.getInstance().getHeightPix();
AliUserLog.i(TAG, "deviceHeight = " + deviceHeight);
} catch (Exception e) {
AliUserLog.e(TAG, e);
}
}
public KeyBoardHeightListenerView init() {
if (!isShowing()) {
final View view = mActivity.getWindow().getDecorView();
// 延迟加载popup 如果不加延迟就会报错因为根view还没渲染
view.post(new Runnable() {
@Override
public void run() {
try {
if (!mActivity.isFinishing()) {
showAtLocation(view, Gravity.NO_GRAVITY, 0, 0);
}
} catch (Exception e) {
AliUserLog.e(TAG, e);
}
}
});
}
return this;
}
@Override
public void onGlobalLayout() {
if (null == rect) {
rect = new Rect();
}
rootView.getWindowVisibleDisplayFrame(rect);
if (rect.bottom > heightMax) {
heightMax = rect.bottom;
}
// 两者的差值就是键盘的高度
int keyboardHeight = heightMax - rect.bottom;
AliUserLog.i(TAG, "heightMax = " + heightMax + " ,rect.bottom = " + rect.bottom + " ,originKeyboardHeight = " + keyboardHeight);
if (isIntercept && keyboardHeight == 0) {//拦截第一次为0的情况
return;
}
isIntercept = false;
//放过0-150的情况 这样可以进行数据重置
// if (keyboardHeight < 150) {//去杂数据 状态栏高度变化导致的回调 0-150之间过滤掉
// keyboardHeight = 0;
// } else
if (keyboardHeight > deviceHeight * 0.75) {//兼容某些小米及三星手机弹窗是实际二倍问题
//键盘高度大于屏幕的0.75 减半 防止测量错误
keyboardHeight = keyboardHeight / 2;
} else if (keyboardHeight >= deviceHeight * 0.60) {//兼容登录卡片比实际高的问题
//键盘高度大于屏幕的0.6 防止测量错误
keyboardHeight = (deviceHeight * 3) / 5 - CommonUtil.dp2Px(mActivity, 132);
} else if (150 < keyboardHeight && keyboardHeight < deviceHeight * 0.4) {//兼容登录卡片比实际低的问题
//键盘高度小于屏幕的0.4 防止测量错误
keyboardHeight = (deviceHeight * 2) / 5;
}
AliUserLog.i(TAG, "preKeyboardHeight = " + preKeyboardHeight + " ,keyboardHeight = " + keyboardHeight);
if (preKeyboardHeight == keyboardHeight) {
//去重 高度相同则不处理
return;
}
preKeyboardHeight = keyboardHeight;
if (preKeyboardHeight > 0 && preKeyboardHeight < 150) {
keyboardHeight = keyboardHeight - preKeyboardHeight;
}
if (keyboardHeight == 0) {//键盘消失后 保证监控到键盘弹起
setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
} else {//键盘弹起则要保证键盘驻留 不被锁屏隐藏
setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED);
}
if (listener != null) {
listener.onHeightChanged(keyboardHeight);
}
}
public KeyBoardHeightListenerView setHeightListener(HeightListener listener) {
this.listener = listener;
return this;
}
public interface HeightListener {
void onHeightChanged(int height);
}
}
监听方法实现
/**
* 适配键盘 防止遮挡
* 监听键盘弹起显示背景阴影
*/
public void initWrapper() {
keyBoardHeightListenerView = new KeyBoardHeightListenerView(getActivity())
.init().setHeightListener(new KeyBoardHeightListenerView.HeightListener() {
@Override
public void onHeightChanged(int height) {//依赖于软键盘是否弹起
LoggerFactory.getTraceLogger().info(getCurrentLoginPageState() + " - " + TAG, "onHeightChanged height: " +
height + " ,keyBoardIsShow:" + keyBoardIsShow);
if (null == mLoginCardView) {
LoggerFactory.getTraceLogger().info(getCurrentLoginPageState() + " - " + TAG, "mLoginCardView is null");
return;
}
if (!isVisible) {
AliUserLog.i(getCurrentLoginPageState() + " - " + TAG, "fragment 不可见,不响应键盘事件");
return;
}
if (getDropListenerData()) {//延时
AliUserLog.i(getCurrentLoginPageState() + " - " + TAG, "阻塞");
return;
}
if (height > 150) {
keyBoardIsShow = true;
mLoginCardView.reSetKeyBoardState(true);
reSetLoginCardViewHeightWrapper(height, false);
} else {
keyBoardIsShow = false;
mLoginCardView.reSetKeyBoardState(false);
}
}
});
}
调整卡片高度方法实现
/**
* 接受外部调用 和软键盘可以无关
*
* @param keyBoardHeight
* @param force
*/
public void reSetLoginCardViewHeightWrapper(final int keyBoardHeight, final boolean force) {
try {
if (loginCardIsMoving || null == mActivity) {//正在移动不用响应
return;
}
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
if (keyBoardHeight > 0 && loginCardViewOriginHeight == 0) {//第一次展示
reSetLoginCardViewHeight(true, keyBoardHeight, force);
} else if (keyBoardHeight > 0) {//调整再次展示
reSetLoginCardViewHeight(true, keyBoardHeight, force);
} else if (keyBoardHeight <= 0 && loginCardViewOriginHeight > 0) {//隐藏
reSetLoginCardViewHeight(false, keyBoardHeight, force);
hideSoftKeyBoard();
}
}
});
} catch (Exception e) {
AliUserLog.e(getCurrentLoginPageState() + " - " + TAG, "reSetLoginCardViewHeightWrapper,e = ", e);
}
}
卡片外层包装方法
/**
* 主动隐藏软键盘
*/
public void hideSoftKeyBoard() {
AliUserLog.i(getCurrentLoginPageState() + " - " + TAG, "hideSoftKeyBoard");
keyBoardIsShow = false;
KeyBoardUtil.closeInputMethod(mLoginView);
}
/**
* 接受外部调用 和软键盘可以无关
*
* @param keyBoardHeight
* @param force
*/
public void reSetLoginCardViewHeightWrapper(final int keyBoardHeight, final boolean force) {
try {
if (loginCardIsMoving || null == mActivity) {//正在移动不用响应
return;
}
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
if (keyBoardHeight > 0 && loginCardViewOriginHeight == 0) {//第一次展示
reSetLoginCardViewHeight(true, keyBoardHeight, force);
} else if (keyBoardHeight > 0) {//调整再次展示
reSetLoginCardViewHeight(true, keyBoardHeight, force);
} else if (keyBoardHeight <= 0 && loginCardViewOriginHeight > 0) {//隐藏
reSetLoginCardViewHeight(false, keyBoardHeight, force);
hideSoftKeyBoard();
}
}
});
} catch (Exception e) {
AliUserLog.e(getCurrentLoginPageState() + " - " + TAG, "reSetLoginCardViewHeightWrapper,e = ", e);
}
}
拉起卡片动画
/**
* 重制登录卡片高度
* 根据主按钮进行换算
*
* @param isPullUp 是否拉起键盘
* @param keyBoardHeight 键盘高度
* @param force 强制弹起
*/
private void reSetLoginCardViewHeight(boolean isPullUp, final int keyBoardHeight, boolean force) {
reSetLoginCardViewHeight(isPullUp, keyBoardHeight, force, true);
}
/**
* 重制登录卡片高度
* 根据主按钮进行换算
*
* @param isPullUp 是否拉起键盘
* @param keyBoardHeight 键盘高度
* @param force 强制弹起
* @param hasAnimation 有无动画
*/
private void reSetLoginCardViewHeight(boolean isPullUp, final int keyBoardHeight, boolean force, boolean hasAnimation) {
try {
AliUserLog.i(getCurrentLoginPageState() + " - " + TAG, "reSetLoginCardViewHeight");
if (!isVisible) {
return;
}
if (isPullUp && mLoginCardView.shouldPullUpWhenKeyboardShow()) {
showLoginViewMask();
int anchorKeyBoardHeight = CommonUtil.dp2Px(mActivity, 80);
if (mLoginCardView.bottomContainer.getVisibility() == View.VISIBLE) {
anchorKeyBoardHeight = CommonUtil.dp2Px(mActivity, 60);
}
if (keyBoardHeight <= anchorKeyBoardHeight) {
return;
}
final int modifySize = keyBoardHeight - anchorKeyBoardHeight;
if (loginCardViewOriginHeight == 0) {
loginCardViewOriginHeight = mLoginCardView.loginCardView.getLayoutParams().height;
}
int loginCardViewPreHeight = mLoginCardView.loginCardView.getLayoutParams().height;
AliUserLog.i(getCurrentLoginPageState() + " - " + TAG, "loginCardViewOriginHeight = " + loginCardViewOriginHeight +
" ,loginCardPullUpHeight = " + loginCardPullUpHeight + " ,modifySize = " + modifySize +
" ,loginCardViewPreHeight = " + loginCardViewPreHeight);
if (loginCardPullUpHeight >= modifySize) {//防止向下调整
return;
}
if (!hasAnimation) {
ViewGroup.LayoutParams layoutParams = mLoginCardView.loginCardView.getLayoutParams();
layoutParams.height = loginCardViewOriginHeight + modifySize;
mLoginCardView.loginCardView.setLayoutParams(layoutParams);
ViewGroup.LayoutParams btnLayoutParams = mLoginCardView.getMainButton().getLayoutParams();
((RelativeLayout.LayoutParams) btnLayoutParams).bottomMargin =
((RelativeLayout.LayoutParams) btnLayoutParams).bottomMargin + modifySize;
mLoginCardView.getMainButton().setLayoutParams(btnLayoutParams);
loginCardPullUpHeight = modifySize;
return;
}
loginCardIsMoving = true;
// 平移 translation
upValueAnimator = ValueAnimator.ofInt(loginCardViewPreHeight,
modifySize - loginCardPullUpHeight + loginCardViewPreHeight);
upValueAnimator.setDuration(300);
upValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
try {
int val = (Integer) valueAnimator.getAnimatedValue();
ViewGroup.LayoutParams layoutParams = mLoginCardView.loginCardView.getLayoutParams();
int changeVal = val - layoutParams.height;
layoutParams.height = val;
mLoginCardView.loginCardView.setLayoutParams(layoutParams);
ViewGroup.LayoutParams btnLayoutParams = mLoginCardView.getMainButton().getLayoutParams();
((RelativeLayout.LayoutParams) btnLayoutParams).bottomMargin =
((RelativeLayout.LayoutParams) btnLayoutParams).bottomMargin + changeVal;
mLoginCardView.getMainButton().setLayoutParams(btnLayoutParams);
} catch (Exception e) {
LoggerFactory.getTraceLogger().error(getCurrentLoginPageState() + " - " + TAG, "reSetLoginCardViewHeight e = ", e);
}
}
});
upValueAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
loginCardPullUpHeight = modifySize;
onPullUpStart();
}
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
loginCardIsMoving = false;
if (null != upValueAnimator) {
upValueAnimator.cancel();
upValueAnimator = null;
}
onPullUpEnd();
}
});
upValueAnimator.start();
} else if (!isPullUp && (force || mLoginCardView.shouldPullDownWhenKeyboardHide()) && loginCardViewOriginHeight > 0) {
hideLoginViewMask();
loginCardIsMoving = true;
downValueAnimator = ValueAnimator.ofInt(
mLoginCardView.loginCardView.getLayoutParams().height, loginCardViewOriginHeight);
downValueAnimator.setDuration(300);
downValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
int val = (Integer) valueAnimator.getAnimatedValue();
ViewGroup.LayoutParams layoutParams = mLoginCardView.loginCardView.getLayoutParams();
int changeVal = layoutParams.height - val;
layoutParams.height = val;
mLoginCardView.loginCardView.setLayoutParams(layoutParams);
ViewGroup.LayoutParams btnLayoutParams = mLoginCardView.getMainButton().getLayoutParams();
((RelativeLayout.LayoutParams) btnLayoutParams).bottomMargin =
((RelativeLayout.LayoutParams) btnLayoutParams).bottomMargin - changeVal;
mLoginCardView.getMainButton().setLayoutParams(btnLayoutParams);
}
});
downValueAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
onPullDownStart();
}
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
loginCardPullUpHeight = 0;
loginCardViewOriginHeight = 0;
loginCardIsMoving = false;
if (isWaitKeyboardPullDown) {
isWaitKeyboardPullDown = false;
changeLoginView(tempLoginBaseView, tempLoginBasePresenter, tempIsAliPayLoginPage);
}
if (null != downValueAnimator) {
downValueAnimator.cancel();
downValueAnimator = null;
}
onPullDownEnd();
}
});
downValueAnimator.start();
}
} catch (Exception e) {
AliUserLog.e(getCurrentLoginPageState() + " - " + TAG, "reSetLoginCardViewHeight,e = ", e);
}
}
键盘上升及下滑事件接口
/**
* 卡片上升开始
*/
protected void onPullUpStart() {
if (null != mLoginCardView) {
mLoginCardView.onPullUpStart();//LoginBaseView
}
if (null != mLoginCardView && null != mLoginCardView.loginBasePresenter) {
mLoginCardView.loginBasePresenter.onPullUpStart();//LoginBasePresenter
}
}
/**
* 卡片上升完成
*/
protected void onPullUpEnd() {
if (null != mLoginCardView) {
mLoginCardView.onPullUpEnd();//LoginBaseView
}
if (null != mLoginCardView && null != mLoginCardView.loginBasePresenter) {
mLoginCardView.loginBasePresenter.onPullUpEnd();//LoginBasePresenter
}
}
/**
* 卡片下滑开始
*/
protected void onPullDownStart() {
if (null != mLoginCardView) {
mLoginCardView.onPullDownStart();//LoginBaseView
}
if (null != mLoginCardView && null != mLoginCardView.loginBasePresenter) {
mLoginCardView.loginBasePresenter.onPullDownStart();//LoginBasePresenter
}
}
/**
* 卡片下滑完成
*/
protected void onPullDownEnd() {
if (null != mLoginCardView) {
mLoginCardView.onPullDownEnd();//LoginBaseView
}
if (null != mLoginCardView && null != mLoginCardView.loginBasePresenter) {
mLoginCardView.loginBasePresenter.onPullDownEnd();//LoginBasePresenter
}
}
View.OnClickListener clickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
loginInputAccountPresenter.loginBaseFragmentWeakReference.get().showSoftKeyBoard(inputPhoneView.getEditText());
hideAccountList();
}
};
inputPhoneView.setOnClickListener(clickListener);
inputPhoneView.getAreaTv().setOnClickListener(clickListener);
inputPhoneView.getEditText().setOnClickListener(clickListener);
焦点联动
子类卡片重写父类卡片中的方法,实现键盘弹起的效果实现焦点联动
@Override
protected void onPullUpEnd() {
super.onPullUpEnd();
if ((isClickUpButton || initShowList) && cardView.getVisibility() != View.VISIBLE) {
//(是否会点击了展示历史账号按钮 || 非切换账号过来) && 没有在展示
showAccountList(true, false);
isClickUpButton = false;
initShowList = false;
}
}
@Override
protected void onPullDownStart() {
super.onPullDownStart();
hideAccountList();
KeyBoardUtil.closeInputMethod(inputPhoneView.getEditText());//防止键盘没隐藏
}
@Override
protected void onPullDownEnd() {
super.onPullDownEnd();
hideAccountList();
inputPhoneView.showBorder(false);
inputPhoneView.cleanBtn.setVisibility(View.GONE);
inputPhoneView.getEditText().setFocusable(false);
}
public class KeyBoardUtil {
private final static String TAG = "KeyBoardUtil";
public static boolean isKeyBoardShowing(View view) {
try {
InputMethodManager imm = (InputMethodManager) LauncherApplicationAgent.getInstance().
getMicroApplicationContext().getApplicationContext().getSystemService(Context.INPUT_METHOD_SERVICE);
AliUserLog.i(TAG, imm.isActive(view) + "");
return imm.isActive(view);
} catch (Exception e) {
AliUserLog.e(TAG, "closeInputMethod exception" + e.getMessage());
return false;
}
}
public static boolean isKeyBoardShowing() {
try {
InputMethodManager imm = (InputMethodManager) LauncherApplicationAgent.getInstance().
getMicroApplicationContext().getApplicationContext().getSystemService(Context.INPUT_METHOD_SERVICE);
AliUserLog.i(TAG, imm.isActive() + "");
return imm.isActive();
} catch (Exception e) {
AliUserLog.e(TAG, "closeInputMethod exception" + e.getMessage());
return false;
}
}
/**
* 关闭软键盘
*
* @param view
*/
public static void closeInputMethod(View view) {
try {
InputMethodManager imm = (InputMethodManager) LauncherApplicationAgent.getInstance().
getMicroApplicationContext().getApplicationContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
} catch (Exception e) {
AliUserLog.e(TAG, "closeInputMethod exception" + e.getMessage());
}
}
/**
* 打开软键盘
*
* @param activity
* @param view
* @param delay 延时
*/
public static void openInputMethodDelay(final Activity activity, final View view, long delay) {
try {
activity.getWindow().getDecorView().postDelayed(new Runnable() {
@Override
public void run() {
openKeyBoardInner(activity, view);
}
}, delay);
} catch (Exception e) {
AliUserLog.e(TAG, "openInputMethodDelay exception" + e.getMessage());
}
}
/**
* 打开软键盘
*
* @param activity
* @param view
*/
public static void openInputMethod(final Activity activity, final View view) {
try {
activity.getWindow().getDecorView().post(new Runnable() {
@Override
public void run() {
openKeyBoardInner(activity, view);
}
});
} catch (Exception e) {
AliUserLog.e(TAG, "openInputMethod exception" + e.getMessage());
}
}
/**
* 打开键盘行动类
*
* @param activity
* @param view
*/
private static void openKeyBoardInner(final Activity activity, final View view) {
try {
view.requestFocus();
if (view instanceof APSafeEditText) {
APSafeEditText apSafeEditText = (APSafeEditText) view;
if (apSafeEditText.isPasswordType()) {
apSafeEditText.showSafeKeyboard();
} else {
InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.showSoftInput(view, 0);
}
} else {
InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.showSoftInput(view, 0);
}
} catch (Exception e) {
AliUserLog.e(TAG, "openKeyBoardInner exception" + e.getMessage());
}
}
}
弹窗键盘适配
键盘弹窗遮挡需要根据键盘弹出的高度进行适配
定义弹窗外层布局
public class KeyboardLayout extends FrameLayout {
private KeyboardLayoutListener mListener;
private boolean mIsKeyboardActive = false; //输入法是否激活
private int mKeyboardHeight = 0; // 输入法高度
public KeyboardLayout(Context context) {
this(context, null, 0);
}
public KeyboardLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public KeyboardLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr); // 监听布局变化
getViewTreeObserver().addOnGlobalLayoutListener(new KeyboardOnGlobalChangeListener());
}
public void setKeyboardListener(KeyboardLayoutListener listener) {
mListener = listener;
}
public KeyboardLayoutListener getKeyboardListener() {
return mListener;
}
public boolean isKeyboardActive() {
return mIsKeyboardActive;
}
/**
* 获取输入法高度
*
* @return
*/
public int getKeyboardHeight() {
return mKeyboardHeight;
}
public interface KeyboardLayoutListener {
/**
* @param isActive 输入法是否激活
* @param keyboardHeight 输入法面板高度
*/
void onKeyboardStateChanged(boolean isActive, int keyboardHeight);
}
private class KeyboardOnGlobalChangeListener implements ViewTreeObserver.OnGlobalLayoutListener {
int mScreenHeight = 0;
private int getScreenHeight() {
if (mScreenHeight > 0) {
return mScreenHeight;
}
mScreenHeight = ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE))
.getDefaultDisplay().getHeight();
return mScreenHeight;
}
@Override
public void onGlobalLayout() {
Rect rect = new Rect(); // 获取当前页面窗口的显示范围
((Activity) getContext()).getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
int screenHeight = getScreenHeight();
int keyboardHeight = screenHeight - rect.bottom; // 输入法的高度
boolean isActive = false;
if (Math.abs(keyboardHeight) > screenHeight / 3) {
isActive = true; // 超过屏幕三分之一则表示弹出了输入法
mKeyboardHeight = keyboardHeight;
}
mIsKeyboardActive = isActive;
if (mListener != null) {
mListener.onKeyboardStateChanged(isActive, keyboardHeight);
}
}
}
}
布局文件
<?xml version="1.0" encoding="utf-8"?>
<com.alipay.mobile.verifyidentity.module.dynamic.ui.KeyboardLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:id="@+id/scrollView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true"
android:fitsSystemWindows="true"
android:scrollbars = "none">
<com.alipay.mobile.verifyidentity.ui.APRelativeLayout
android:id="@+id/dynamic_root"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</ScrollView>
</com.alipay.mobile.verifyidentity.module.dynamic.ui.KeyboardLayout>
添加监听和执行滑动
mRootView = findViewById(R.id.dynamic_root);
container = findViewById(R.id.container);
scrollView = findViewById(R.id.scrollView);
/**
* 监听键盘状态,布局有变化时,靠scrollView去滚动界面
*/
public void addLayoutKeyboardListener() {
container.setKeyboardListener(new KeyboardLayout.KeyboardLayoutListener() {
@Override
public void onKeyboardStateChanged(boolean isActive, int keyboardHeight) {
VerifyLogCat.i(TAG, "isActive:" + isActive + " keyboardHeight:" + keyboardHeight);
try {
scrollToBottom();
} catch (Exception e) {
VerifyLogCat.e(TAG, "onKeyboardStateChanged Exception", e);
}
}
});
}
/**
* 弹出软键盘时将SVContainer滑到底
*/
private void scrollToBottom() {
if (null == mRootView) {
return;
}
mRootView.postDelayed(new Runnable() {
@Override
public void run() {
try {
scrollView.smoothScrollTo(0, mRootView.getBottom() / 6);
} catch (Exception e) {
VerifyLogCat.e(TAG, "scrollToBottom Exception", e);
}
}
}, 100);
}