检测Webview中键盘是否激活

3
我在Stack上还没有找到解决这个问题的方法。
我有一个Webview应用程序。我希望能够检测键盘何时处于活动状态以及何时不处于活动状态。似乎当这些变化发生在Webview中时,它无法检测到这些变化。
我想在这些不同的状态下执行操作。在iOS上,使用监听器监听键盘是否处于活动状态非常简单。参考UIKeyboardWillShow / Hide。
在Android中是否有与这些观察者相同的功能?
希望问题已经足够解释清楚了。

可能是[Android中活动中的SoftKeyboard打开和关闭侦听器?]的重复(https://dev59.com/Ml8e5IYBdhLWcg3w7uDP) - SripadRaj
不这么想。那些答案似乎包括原生内置的“EditText”,而我有一个带有文本字段的Webview。我需要知道这些字段何时处于活动状态。在iOS上很简单,但在Android上似乎还有更多要做。 - The Normal One
为什么不呢?我假设你的Web视图有文本字段,这些字段默认会打开键盘。你可以将监听器附加到Web视图上。你可以尝试一下,我认为它应该可以工作。 - SripadRaj
1个回答

0

我曾经为此苦苦挣扎了一周左右,找到了很多资料。这是我的解决方案,真心希望它能对你有所帮助。

在我的情况下,我有一个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);
}

这应该就可以解决问题了 :) 你觉得呢?


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