要實現如上圖效果: 注意不是將頁面總體滑上去,而是讓頁面上滑一部分,以達到不遮擋登陸按鈕的效果java
實現思路:android
首先在Manifest文件中對相應的Activity配置屬性windowSoftInputMode,讓Activity可以在鍵盤彈起和收回時有所響應。bash
<activity
android:name=".ui.activitys.login.LoginPwdActivity"
android:launchMode="singleTask"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden|adjustPan" />
複製代碼
監聽方法:app
/**
* Register soft input changed listener.
*
* @param activity The activity.
* @param listener The soft input changed listener.
*/
public static void registerSoftInputChangedListener(final Activity activity,
final OnSoftInputChangedListener listener) {
final int flags = activity.getWindow().getAttributes().flags;
if ((flags & WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS) != 0) {
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
final View contentView = activity.findViewById(android.R.id.content);
sContentViewInvisibleHeightPre = getContentViewInvisibleHeight(activity);
onSoftInputChangedListener = listener;
onGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (onSoftInputChangedListener != null) {
int height = getContentViewInvisibleHeight(activity);
if (sContentViewInvisibleHeightPre != height) {
onSoftInputChangedListener.onSoftInputChanged(height);
sContentViewInvisibleHeightPre = height;
}
}
}
};
contentView.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
}
private static int getContentViewInvisibleHeight(final Activity activity) {
final View contentView = activity.findViewById(android.R.id.content);
final Rect outRect = new Rect();
contentView.getWindowVisibleDisplayFrame(outRect);
return contentView.getBottom() - outRect.bottom;
}
/**
* Register soft input changed listener.
*
* @param activity The activity.
*/
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public static void unregisterSoftInputChangedListener(final Activity activity) {
final View contentView = activity.findViewById(android.R.id.content);
contentView.getViewTreeObserver().removeOnGlobalLayoutListener(onGlobalLayoutListener);
onSoftInputChangedListener = null;
onGlobalLayoutListener = null;
}
public interface OnSoftInputChangedListener {
void onSoftInputChanged(int height);
}
複製代碼
利用view的topMargin來實現滑動動畫ide
final ViewWrapper wrapper = new ViewWrapper(scrollview);
SoftInputUtil.registerSoftInputChangedListener(this,
new SoftInputUtil.OnSoftInputChangedListener() {
@Override
public void onSoftInputChanged(int height) {
HhixLog.e(TAG, SoftInputUtil.isSoftInputVisible(LoginPwdActivity.this) + ",height:" + height + ",tip bottom:" + tvTips.getBottom());
versionTv.setVisibility(SoftInputUtil.isSoftInputVisible(LoginPwdActivity.this) ? View.GONE : View.VISIBLE);
if (SoftInputUtil.isSoftInputVisible(LoginPwdActivity.this)) {
distance = height - (IMApplication.getInstance().screenSize.screenHeight - tipsBottom - UIUtils.dip2px(IMApplication.getInstance(), 24));
if (distance > 0) {
ivWelcome.setVisibility(View.INVISIBLE);
ObjectAnimator animator = ObjectAnimator.ofInt(wrapper, "topMargin", 0, -distance);
animator.setDuration(200).start();
}
} else {
if (distance > 0) {
ivWelcome.setVisibility(View.VISIBLE);
ObjectAnimator animator = ObjectAnimator.ofInt(wrapper, "topMargin", -distance, 0);
animator.setDuration(200).start();
}
}
}
});
/** * Return whether soft input is visible. * <p>The minimum height is 200</p> * * @param activity The activity. * @return {@code true}: yes<br>{@code false}: no */
public static boolean isSoftInputVisible(final Activity activity) {
return isSoftInputVisible(activity, 200);
}
/** * Return whether soft input is visible. * * @param activity The activity. * @param minHeightOfSoftInput The minimum height of soft input. * @return {@code true}: yes<br>{@code false}: no */
public static boolean isSoftInputVisible(final Activity activity, final int minHeightOfSoftInput) {
return getContentViewInvisibleHeight(activity) >= minHeightOfSoftInput;
}
class ViewWrapper {
private View mTarget;
private FrameLayout.LayoutParams mParams;
public ViewWrapper(View target) {
mTarget = target;
mParams = (FrameLayout.LayoutParams) mTarget.getLayoutParams();
}
public void setTopMargin(int topMargin) {
mParams.setMargins(0, topMargin, 0, 0);
mTarget.setLayoutParams(mParams);
mTarget.requestLayout();
}
public int getTopMargin() {
return mParams.topMargin;
}
}
複製代碼