我需要做一件非常简单的事情-查看是否显示了软键盘.这在Android中是可能的吗?

推荐答案

NEW ANSWER added Jan 25th 2012

在写了下面的答案后,有人告诉我ViewTreeObserver和friends的存在,这些API从版本1开始就潜伏在SDK中.

不需要自定义布局类型,一个更简单的解决方案是为活动的根视图提供一个已知ID,比如@+id/activityRoot,将GlobalLayoutListener挂接到ViewTreeObserver,然后从那里计算活动的视图根和窗口大小之间的大小差:

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

容易的

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

ORIGINAL ANSWER

是的,这是可能的,但这远比它应该的难.

如果我需要关心键盘何时出现和消失(这是很常见的),那么我要做的就是将我的顶级布局类自定义为一个覆盖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);       
    }

    }

然后在你的活动课上...

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相关问答推荐

RippleTheme在作曲material 1.7.0中被废弃

错误:无法解析Symbol@style/Theme. Androidstudio in AndroidManifest.html for Kotlin Android Development''

Android深度链接配置中的URL片段匹配'

合成 colored颜色 的GSON反序列化

如何使用Jetpack Compose实现此底表?

Android App Google AdMob";广告加载失败:3;带有测试ID,&q;广告加载失败:1 for My Gahad

Android从已连接的设备获得GATT

如何在 compose 中使用可变对象?

expo 上的 socket.io 无法从 Android 连接

Android 构建失败:找不到 flexbox2.0.1.aar

请求访问小部件中的位置权限

Android 模拟器 Wifi 连接没有互联网

如何让这个三角形指示器在 android jetpack compose 中旋转和移动?

获取 ArithmeticException:除以零,但我没有在任何地方除以零

Jetpack 将 Grid 与基于大小的自适应列数组合在一起

无法为:app@debug/compileClasspath解析依赖项com.github.dhaval2404:imagepicker-support:1.7.1

如何在包含 Jetpack Compose 内容的布局中使用权重

compose FontFamily 错误:必须初始化变量

为什么使用 React Native 和 expo 创建的 APK 体积这么大?

compose :为什么以记住启动的列表触发方式与快照不同