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

时间:2016-10-17 13:49:21

标签: android android-softkeyboard

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

  

我知道,以前发过类似的问题   (How to check visibility of software keyboard in Android?),   但是,有大量赞成票的最后答案来自 2012 ,以及   我想从那时起Android就发生了很多事情。

那么,我可以检测键盘是否打开/可见吗?

4 个答案:

答案 0 :(得分:4)

创建一个类

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();
            }
        }
    }
}

然后在您的活动的onCreate中添加以下行

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

其中R.id.parent是活动的父布局的id,softKeyboardStateListener定义如下

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

        }

        @Override
        public void onSoftKeyboardClosed() {

        }
    };

答案 1 :(得分:2)

我们现在有Android N,但仍然无法直接检测键盘是否打开。只有解决屏幕尺寸的解决方案才能解决。然而,有些时候没有全面保护,有时会在屏幕旋转或Android N上进入多窗口模式时给出错误的信号。

答案 2 :(得分:1)

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

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

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

希望我帮助过:D

答案 3 :(得分:1)

我之前遇到过同样的问题。经过大量的反复试验并遵循其他人的建议,我提出了适用于我的实施方案。这是link