【问题标题】:Detecting when the keyboard is active in a webview检测键盘何时在 web 视图中处于活动状态
【发布时间】:2018-03-05 12:23:50
【问题描述】:

我还没有找到任何方法在堆栈上解决这个问题。

我的应用中有一个网络视图。我希望能够检测到键盘何时处于活动状态以及何时处于非活动状态。当它们在 webview 中发生时,似乎它无法检测到这些变化。

我想对这些不同的状态执行操作。在 iOS 上,当键盘处于活动状态时,它的监听器非常简单。参考 UIKeyboardWillShow/Hide。

android 中是否有与这些观察者在 android 中相同的功能?

希望这个问题得到了充分的解释。

【问题讨论】:

  • 不这么认为。这些答案似乎包括内置在“EditText”中的本机,并且我有一个带有文本字段的网络视图。我需要知道这些字段何时处于活动状态。这在 ios 上很简单,但在 Android 上似乎还有更多。
  • 为什么不呢?我假设您的 Web 视图具有默认打开键盘的文本字段。您可以将侦听器附加到 webview。你可以试试,我觉得应该可以。

标签: java android webview keyboard android-webview


【解决方案1】:

所以我为此苦苦挣扎了一周左右,找到了很多材料这是我的解决方案,我真的希望它对你有用。

所以在我的例子中,我有一个 Activity,我调用了一个包含 Webview 的片段,所以它比我想象的要复杂得多。

基本上问题是片段缺少这一行:

getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);

所以它没有识别出 webview 内部的高度变化。

无论如何,让我们来看看代码:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = super.onCreateView(inflater, container, savedInstanceState);
    //mWebView.postUrl("https://www.google.com/");
    final View activityRootView = view;
    layoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            Rect r = new Rect();
            //r will be populated with the coordinates of your view that area still visible.
            activityRootView.getWindowVisibleDisplayFrame(r);
            // This variable was created only for Debug purposes and 
            // to see the height change when clicking on a field inside mWebView
            int screenHeight = activityRootView.getRootView().getHeight();
            Log.d("onGlobalLayout", "rect: " + r.toString());
            Log.d("onGlobalLayout", "screenHeight: " + screenHeight);

            //The difference on the heights from bottom to top and on the root height
            int heightDiff = screenHeight - (r.bottom - r.top);
            Log.d("onGlobalLayout", "heightDiff: " + heightDiff);

            //I suggest to put 250 on resources and retrieve from there using getResources().getInteger() to have better order
            float dpx = dpToPx(getActivity(), 250);

            if (previousHeightDiff != heightDiff) {
                if (heightDiff > dpx) {
                    isSoftKeyboardPresent = true;
                } else {
                    isSoftKeyboardPresent = false;
                }
                previousHeightDiff = heightDiff;
            }
        }
    };
    activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(layoutListener);
    getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
    return view;
}

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

记得在你的 AndroidManifest.xml 中设置 Activity 设置为:android:windowSoftInputMode="adjustResize|stateHidden"

片段内的变量是:

public boolean isSoftKeyboardPresent = false;
private int previousHeightDiff = -1;// this is used to avoid multiple assignments
private ViewTreeObserver.OnGlobalLayoutListener layoutListener = null;

终于

@Override
public void onPause() {
    super.onPause();
    final View activityRootView = getActivity().findViewById(R.id.page_content);
    activityRootView.getViewTreeObserver().removeOnGlobalLayoutListener(layoutListener);
}

这应该可以解决问题 :) 那么你怎么看?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-23
    • 2011-05-04
    相关资源
    最近更新 更多