安卓:如何判断软键盘是否正在显示?

22
这里有个难题: 我展示了一个带有3个输入字段和2个按钮的屏幕,这些控件都位于选项卡内(总共有3个选项卡,它们在屏幕底部)。这2个按钮设置在屏幕左下角和右下角,紧挨着选项卡。当我点击输入字段时,选项卡和按钮都会被推到键盘上方。
我希望只将按钮向上推,而将选项卡留在原位,即屏幕底部。我考虑一旦确定软键盘弹出,就将选项卡的可见性设置为“GONE”,一旦软键盘消失,就将其可见性设置为“VISIBLE”。
是否有某种监听软键盘或输入字段的机制?也许可以通过编辑文本的 OnFocusChangeListener 来巧妙解决问题?如何确定键盘是否可见?

看看这个:https://dev59.com/cm445IYBdhLWcg3wq8Lp#31090451对我很管用。 - Christopher Hackl
可能是如何在Android中检查软键盘的可见性?的重复问题。 - afathman
6个回答

5
似乎无法确定键盘是否正在显示。您可能希望在清单文件中使用“windowSoftInputMode” xml 标签禁用它:http://developer.android.com/reference/android/R.attr.html#windowSoftInputMode。或者您可以查看如何取消焦点以隐藏键盘:在不进行任何键盘操作的活动上隐藏软键盘。但这两种方法都不能完全解决您的问题。我记得曾阅读过一篇强烈建议不要将选项卡放在屏幕底部,而是放在顶部以提高界面清晰度的博客文章。我建议您对此进行跟进。

3
迄今为止,是否仍然无法可靠地确定软键盘是否已显示?自从五年前… - SePröbläm

1
据我所知,你无法这样做。
但是,你可以监视布局的大小变化,由于键盘显示是大小调整的主要原因,因此你可能能够假设键盘是否显示。
以下是一个用于监视布局大小变化的示例代码。只需将此布局用作原始布局的父级,并使用其侦听器即可。如果高度减小,则可以假设键盘已显示,如果增加,则可以假设它已关闭。
public class LayoutSizeChangedSensorFrameLayout extends FrameLayout {
    public enum SizeChange {
        HEIGHT_INCREASED, HEIGHT_DECREASED, WIDTH_INCREASED, WIDTH_DECREASED
    }

    public interface OnLayoutSizeChangedListener {
        void onSizeChanged(EnumSet<SizeChange> direction);
    }

    private OnLayoutSizeChangedListener mLayoutSizeChangeListener;

    public LayoutSizeChangedSensorFrameLayout(final Context context) {
        super(context);
    }

    public LayoutSizeChangedSensorFrameLayout(final Context context, final AttributeSet attributeSet) {
        super(context, attributeSet);
    }

    public LayoutSizeChangedSensorFrameLayout(final Context context, final AttributeSet attrs, final int defStyle) {
        super(context, attrs, defStyle);
    }

  @Override
  protected void onSizeChanged(final int w, final int h, final int oldw, final int oldh) {
      super.onSizeChanged(w, h, oldw, oldh);
      if (mLayoutSizeChangeListener != null) {
          final EnumSet<SizeChange> result = EnumSet.noneOf(SizeChange.class);
          if (oldh > h)
              result.add(SizeChange.HEIGHT_DECREASED);
          else if (oldh < h)
              result.add(SizeChange.HEIGHT_INCREASED);
          if (oldw > w)
              result.add(SizeChange.WIDTH_DECREASED);
          else if (oldw < w)
              result.add(SizeChange.WIDTH_INCREASED);
          if (!result.isEmpty())
              mLayoutSizeChangeListener.onSizeChanged(result);
      }
  }

    public void setOnLayoutSizeChangedListener(final OnLayoutSizeChangedListener layoutSizeChangeListener) {
        this.mLayoutSizeChangeListener = layoutSizeChangeListener;
    }

    public OnLayoutSizeChangedListener getOnLayoutSizeChangeListener() {
        return mLayoutSizeChangeListener;
    }
}

0
这可能有帮助 http://developer.android.com/reference/android/inputmethodservice/InputMethodService.html

https://android.googlesource.com/platform/packages/inputmethods/LatinIME/+/master/java/src/com/android/inputmethod/latin

键盘代码在这里,我已经用grep搜索了一下,但是放弃了,我没有看到任何有用的广播被发送,至少在这里没有。也许你可以去找到存储库中的更低级别的代码,并找到一个有用的意图被发送。第一个链接可能会告诉你它何时变得可见,但我不确定如何告诉它何时变得不可见。

0

在寻找了几个类之后,我终于找到了解决方案。 我决定使用WindowsInset,因为它不像使用全局布局那样每秒钟都会调用。 有一个视频介绍如何使用WindowsInset。链接


0

对我来说可行的解决方案 -

ViewTreeObserver treeObserver = getViewTreeObserver();
        if (treeObserver != null)
            treeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    int pHeight = getResources().getDisplayMetrics().heightPixels;

                Rect visRect = new Rect();
                viewGroup.getWindowVisibleDisplayFrame(visRect);

                boolean keyboardVisible;
                int keyboardHeight= pHeight-currentHeight;
                if (keyboardHeight > (MIN_KEYBOARD_HEIGHT*pHeight))
                {
                    TGVLog.d(debugTag, "keyboardVisible-- "+true);
                    keyboardVisible = true;
                }
                else
                {
                    TGVLog.d(debugTag, "keyboardVisible-- "+false);
                    keyboardVisible = false;
                }
                }
            });

-4
在我的上一个应用程序中,我在显示软键盘方面遇到了一些问题,然后我在清单文件中使用了以下代码:

<activity android:screenOrientation="portrait" android:configChanges="keyboardHidden|orientation" android:name=".rate.Calculator"/>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接