Android EditText 键盘顶起父布局实现流程

在Android开发中,当软键盘弹出时,如果EditText位于软键盘上方,会导致EditText被遮挡。为了解决这个问题,我们需要让父布局随着键盘的弹出而上移,以保证EditText的可见性。下面是实现这个功能的具体步骤:

流程图

graph LR
A[检测键盘弹出事件] --> B[获取键盘高度]
B --> C[设置布局偏移]
C --> D[监听键盘隐藏事件]

步骤说明

1. 检测键盘弹出事件

首先,我们需要监听键盘的弹出和隐藏事件。在Android中,我们可以通过监听View的布局变化来实现。具体步骤如下:

  1. 创建一个自定义的ViewGroup,用于包裹 EditText 和其他需要被顶起的视图。
  2. 重写该ViewGroup的 onLayout 方法,在其中监听布局变化。
  3. 在 onLayout 方法中,判断键盘的状态,如果弹出,则进行下一步操作。

代码示例:

public class KeyboardDetectingViewGroup extends FrameLayout {

    ...

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        
        // 判断键盘是否弹出,并执行相应操作
        if (isKeyboardVisible()) {
            // 获取键盘高度
            int keyboardHeight = getKeyboardHeight();
            // 设置布局偏移
            setLayoutOffset(-keyboardHeight);
        } else {
            // 键盘隐藏时恢复布局
            setLayoutOffset(0);
        }
    }

    ...
}

2. 获取键盘高度

在键盘弹出事件中,我们需要获取键盘的高度,以便后续操作布局。具体步骤如下:

  1. 创建一个类,用于监听View的布局变化。
  2. 在监听回调方法中,获取键盘的高度。

代码示例:

public class KeyboardHeightProvider {

    ...

    private void start() {
        // 监听布局变化
        view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                // 获取键盘高度
                int keyboardHeight = view.getRootView().getHeight() - view.getHeight();
                // 通知监听器键盘高度变化
                if (listener != null) {
                    listener.onKeyboardHeightChanged(keyboardHeight);
                }
            }
        });
    }

    ...
}

3. 设置布局偏移

当键盘弹出时,我们需要将整个布局上移,以保证EditText的可见性。具体步骤如下:

  1. 获取需要被顶起的父布局的 LayoutParams。
  2. 设置 LayoutParams 的 topMargin 值为键盘的高度的负值。

代码示例:

public class KeyboardDetectingViewGroup extends FrameLayout {

    ...

    private void setLayoutOffset(int offset) {
        // 获取父布局的 LayoutParams
        ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) getLayoutParams();
        // 设置布局偏移
        layoutParams.topMargin = offset;
        setLayoutParams(layoutParams);
    }

    ...
}

4. 监听键盘隐藏事件

当键盘隐藏时,我们需要将布局恢复到原来的位置。具体步骤如下:

  1. 监听键盘隐藏事件。
  2. 在监听回调方法中,将布局恢复到原来的位置。

代码示例:

public class KeyboardHeightProvider {

    ...

    private void start() {
        // 监听布局变化
        view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                if (isKeyboardVisible()) {
                    // 获取键盘高度
                    int keyboardHeight = view.getRootView().getHeight() - view.getHeight();
                    // 通知监听器键盘高度变化
                    if (listener != null) {
                        listener.onKeyboardHeightChanged(keyboardHeight);
                    }
                } else {
                    // 键盘隐藏时恢复布局
                    setLayoutOffset(0);
                }
            }
        });