软键盘遮挡问题

1.gif

要实现如上图效果:
注意不是将页面整体滑上去,而是让页面上滑一部分,以达到不遮挡登录按钮的效果

实现思路:

  1. 监听键盘的弹起与收回
  2. 滑动

监听键盘的弹起与收回

首先在Manifest文件中对相应的Activity配置属性windowSoftInputMode,让Activity能够在键盘弹起和收回时有所响应。


监听方法:

/**
 * 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来实现滑动动画

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.
 * 

The minimum height is 200

* * @param activity The activity. * @return {@code true}: yes
{@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
{@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; } }

你可能感兴趣的:(软键盘遮挡问题)