有没有办法检测软键盘是否在 Android 中打开?

Is there a way of detecting whether or not the softkeyboard is open in Android?

我的应用旨在收集数据。但它只需要在键盘可见时收集数据。 仅在用户键入时收集数据是不够的,所以我肯定需要知道键盘是否可见。

I know, similar questions were posted before (How to check visibility of software keyboard in Android?), but the last answer with a serious number of upvotes is from 2012, and I guess a lot of things happened with Android since then.

那么,我可以检测键盘是否 open/visible 吗?

您可能听说过,没有直接的方法。但是,通过检查屏幕尺寸是否已更改,您通常可以使用以下命令找到它:

protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld) {
    super.onSizeChanged(xNew, yNew, xOld, yOld);

    if (yOld > yNew) {
        //Do Stuff Here
    }
}

希望我能帮到你 :D

创建 class

package com.dubaipolice.app.utils;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Rect;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewTreeObserver;

import java.util.LinkedList;
import java.util.List;

/**
 * Created by dev101 on 1/13/15.
 */
public class SoftKeyboardStateHelper implements ViewTreeObserver.OnGlobalLayoutListener {

    float LIMIT = 100;

    public interface SoftKeyboardStateListener {
        void onSoftKeyboardOpened(int keyboardHeightInPx);

        void onSoftKeyboardClosed();
    }

    private final List<SoftKeyboardStateListener> listeners = new LinkedList<SoftKeyboardStateListener>();
    private final View activityRootView;
    private int lastSoftKeyboardHeightInPx;
    private boolean isSoftKeyboardOpened;

    public SoftKeyboardStateHelper(Context context, View activityRootView) {
        this(activityRootView, false);
        Resources r = context.getResources();
        LIMIT = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 100, r.getDisplayMetrics());
    }

    public SoftKeyboardStateHelper(View activityRootView, boolean isSoftKeyboardOpened) {
        this.activityRootView = activityRootView;
        this.isSoftKeyboardOpened = isSoftKeyboardOpened;
        activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(this);
    }

    @Override
    public void onGlobalLayout() {
        final Rect r = new Rect();
        //r will be populated with the coordinates of your view that area still visible.
        activityRootView.getWindowVisibleDisplayFrame(r);

        final int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
        if (!isSoftKeyboardOpened && heightDiff > LIMIT) { // if more than 100 pixels, its probably a keyboard...
            isSoftKeyboardOpened = true;
            notifyOnSoftKeyboardOpened(heightDiff);
        } else if (isSoftKeyboardOpened && heightDiff < LIMIT) {
            isSoftKeyboardOpened = false;
            notifyOnSoftKeyboardClosed();
        }
    }

    public void setIsSoftKeyboardOpened(boolean isSoftKeyboardOpened) {
        this.isSoftKeyboardOpened = isSoftKeyboardOpened;
    }

    public boolean isSoftKeyboardOpened() {
        return isSoftKeyboardOpened;
    }

    /**
     * Default value is zero (0)
     *
     * @return last saved keyboard height in px
     */
    public int getLastSoftKeyboardHeightInPx() {
        return lastSoftKeyboardHeightInPx;
    }

    public void addSoftKeyboardStateListener(SoftKeyboardStateListener listener) {
        listeners.add(listener);
    }

    public void removeSoftKeyboardStateListener(SoftKeyboardStateListener listener) {
        listeners.remove(listener);
    }

    private void notifyOnSoftKeyboardOpened(int keyboardHeightInPx) {
        this.lastSoftKeyboardHeightInPx = keyboardHeightInPx;

        for (SoftKeyboardStateListener listener : listeners) {
            if (listener != null) {
                listener.onSoftKeyboardOpened(keyboardHeightInPx);
            }
        }
    }

    private void notifyOnSoftKeyboardClosed() {
        for (SoftKeyboardStateListener listener : listeners) {
            if (listener != null) {
                listener.onSoftKeyboardClosed();
            }
        }
    }
}

然后在您的 activity 的 onCreate 中,添加以下行

final SoftKeyboardStateHelper softKeyboardStateHelper = new SoftKeyboardStateHelper(context, findViewById(R.id.parent));
        softKeyboardStateHelper.addSoftKeyboardStateListener(softKeyboardStateListener);

其中 R.id.parent 是您的 activity 父布局的 ID,softKeyboardStateListener 定义如下

SoftKeyboardStateHelper.SoftKeyboardStateListener softKeyboardStateListener = new SoftKeyboardStateHelper.SoftKeyboardStateListener() {
        @Override
        public void onSoftKeyboardOpened(int keyboardHeightInPx) {

        }

        @Override
        public void onSoftKeyboardClosed() {

        }
    };

我们目前有 Android N 个,但仍然没有直接的方法来检测键盘是否打开。只有解决方案可用,例如检查屏幕尺寸的解决方案。然而,没有完全证明,有时会发出错误信号,例如在屏幕旋转时或在 Android N.

上进入 multi-window 模式

我之前遇到过同样的问题。经过大量的反复试验并听从其他人的建议,我想出了适合我的实施方案。这里是 link.