android - 如何在 Android 中检查软件键盘的可见性?

标签 android visibility android-softkeyboard

我需要做一件非常简单的事情 - 找出是否显示了软件键盘。这在 Android 中可行吗?

最佳答案

新答案 添加于 2012 年 1 月 25 日

自从写下下面的答案后,有人提示我 ViewTreeObserver 的存在和 friend 们,从版本 1 开始就潜伏在 SDK 中的 API。

不需要自定义布局类型,一个更简单的解决方案是为您的 Activity 的 Root View 提供一个已知 ID,例如 @+id/activityRoot,将 GlobalLayoutListener Hook 到 ViewTreeObserver,然后从那里计算 Activity 的 View 根和窗口大小之间的大小差异:

final View activityRootView = findViewById(R.id.activityRoot);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        int heightDiff = activityRootView.getRootView().getHeight() - activityRootView.getHeight();
        if (heightDiff > dpToPx(this, 200)) { // if more than 200 dp, it's probably a keyboard...
            // ... do something here
        }
     }
});

使用实用程序,例如:

public static float dpToPx(Context context, float valueInDp) {
    DisplayMetrics metrics = context.getResources().getDisplayMetrics();
    return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, valueInDp, metrics);
}

简单!

注意: 您的应用程序必须在 Android Manifest android:windowSoftInputMode="adjustResize" 中设置此标志,否则上述解决方案将不起作用。

原始答案

是的,这是可能的,但它比应有的要难得多。

如果我需要关心键盘何时出现和消失(这很常见),那么我所做的就是将我的顶级布局类自定义为一个覆盖 onMeasure() 的类。基本逻辑是,如果布局发现自己填充的空间明显小于窗口的总面积,那么可能会显示软键盘。

import android.app.Activity;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.widget.LinearLayout;

/*
 * LinearLayoutThatDetectsSoftKeyboard - a variant of LinearLayout that can detect when 
 * the soft keyboard is shown and hidden (something Android can't tell you, weirdly). 
 */

public class LinearLayoutThatDetectsSoftKeyboard extends LinearLayout {

    public LinearLayoutThatDetectsSoftKeyboard(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public interface Listener {
        public void onSoftKeyboardShown(boolean isShowing);
    }
    private Listener listener;
    public void setListener(Listener listener) {
        this.listener = listener;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int height = MeasureSpec.getSize(heightMeasureSpec);
        Activity activity = (Activity)getContext();
        Rect rect = new Rect();
        activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
        int statusBarHeight = rect.top;
        int screenHeight = activity.getWindowManager().getDefaultDisplay().getHeight();
        int diff = (screenHeight - statusBarHeight) - height;
        if (listener != null) {
            listener.onSoftKeyboardShown(diff>128); // assume all soft keyboards are at least 128 pixels high
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);       
    }

    }

然后在你的 Activity 类中...

public class MyActivity extends Activity implements LinearLayoutThatDetectsSoftKeyboard.Listener {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        LinearLayoutThatDetectsSoftKeyboard mainLayout = (LinearLayoutThatDetectsSoftKeyboard)findViewById(R.id.main);
        mainLayout.setListener(this);
        ...
    }


    @Override
    public void onSoftKeyboardShown(boolean isShowing) {
        // do whatever you need to do here
    }

    ...
}

关于android - 如何在 Android 中检查软件键盘的可见性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2150078/

相关文章:

android - 为什么我会在 Google Play 中收到此优化提示

java - 获取本地化日期

Android 使用键盘上的完成按钮单击按钮

java - 软键盘覆盖 PopupWindow 中的 EditText

android - 软键盘隐藏了一半的 EditText

android - 在 android 的 ScrollView 中加载数百个位图图像时出现内存不足错误

Android Studio 找不到现有资源

types - 通过公共(public)函数公开私有(private)类型

php - 如何从 PHP 中的静态方法中看到类的 protected 属性?

wpf - 当 ItemsSource 为空或 null 时,MVVM WPF 将 ListBox 替换为 Label