使用InputMethodManager.showSoftKeyboard()时如何禁用自动完成/建议

时间:2019-11-05 20:11:32

标签: android libgdx

试图修复我的LibGDX应用程序中的一个错误,该错误中一些Android用户报告空格键在其输入中插入了“自动完成”字样。在某些情况下,软键盘甚至不显示自动完成建议。

据我了解,LibGDX不使用“本机” Android UI元素,因此TextField对象在单击时运行以下代码:

public void setOnscreenKeyboardVisible (final boolean visible) {
        handle.post(new Runnable() {
            public void run () {
                InputMethodManager manager = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE);
                if (visible) {
                    View view = ((AndroidGraphics)app.getGraphics()).getView();
                    view.setFocusable(true);
                    view.setFocusableInTouchMode(true);
                    manager.showSoftInput(view, 0);
                } else {
                    manager.hideSoftInputFromWindow(((AndroidGraphics)app.getGraphics()).getView().getWindowToken(), 0);
                }
            }
        });
    }

所以这里有这行显示了键盘:

manager.showSoftInput(view, 0);

我如何设置一些标志或其他内容来告诉键盘禁用自动完成功能?

注意,这仅在某些用户中发生,找不到模式。此外,到目前为止,仅Android 8和9。

1 个答案:

答案 0 :(得分:0)

我搜索了一下,结果发现这根本不简单。

您显示的来自AndroidInput的方法使用视图app.getGraphics().getView()来显示键盘。如another answer中所述,您将需要对该视图进行子类化并覆盖以下方法,以便能够设置输入标志:

@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
    InputConnection connection =  super.onCreateInputConnection(outAttrs);
    // Set flags to disable suggestions. Visible password flag is only needed for some devices.
    outAttrs.inputType |= InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS 
            | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD;
    return connection;
}

除了AndroidGraphics使用的视图不是特别容易子类化。相反,您可以对AndroidInput类进行子类化,并提供不同的输入视图。这是一个示例启动器类:

class AndroidLauncher extends AndroidApplication {

    private View inputView;
    private Handler handle;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Config and init your game class.
        AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
        initialize(new MyGame(), config);

        // Custom view used for showing the keyboard.
        // Most of the code in onCreateInputConnection comes from the GLSurfaceView20 class.
        inputView = new View(this) {
            @Override
            public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
                if (outAttrs != null) {
                    outAttrs.imeOptions |= EditorInfo.IME_FLAG_NO_EXTRACT_UI;
                    // This line is the only different from original source, it disables suggestions.
                    outAttrs.inputType |= InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS
                            | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD;
                }

                return new BaseInputConnection(this, false) {
                    @Override
                    public boolean deleteSurroundingText (int beforeLength, int afterLength) {
                        int sdkVersion = android.os.Build.VERSION.SDK_INT;
                        if (sdkVersion >= 16) {
                            if (beforeLength == 1 && afterLength == 0) {
                                sendDownUpKeyEventForBackwardCompatibility(KeyEvent.KEYCODE_DEL);
                                return true;
                            }
                        }
                        return super.deleteSurroundingText(beforeLength, afterLength);
                    }

                    @TargetApi(16)
                    private void sendDownUpKeyEventForBackwardCompatibility (final int code) {
                        final long eventTime = SystemClock.uptimeMillis();
                        super.sendKeyEvent(new KeyEvent(eventTime, eventTime, KeyEvent.ACTION_DOWN, code, 0, 0,
                                KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE));
                        super.sendKeyEvent(new KeyEvent(SystemClock.uptimeMillis(), eventTime, KeyEvent.ACTION_UP, code, 0, 0,
                                KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE));
                    }
                };
            }
        };
        handle = new Handler();  // handle is private in AndroidInput so we create our own.

        // Android has two different AndroidInput classes depending on SDK versions, create the right one. You can remove one of them if you don't support API < 12.
        if (Build.VERSION.PREVIEW_SDK_INT >= 12) {
           input = new AndroidInputThreePlus(this, this, graphics.getView(), config) {
               @Override
               public void setOnscreenKeyboardVisible(boolean visible) {
                   AndroidLauncher.this.setOnscreenKeyboardVisible(visible);
               }
           };
        } else {
            input = new AndroidInput(this, this, graphics.getView(), config) {
                @Override
                public void setOnscreenKeyboardVisible(boolean visible) {
                    AndroidLauncher.this.setOnscreenKeyboardVisible(visible);
                }
            };
        }
    }

    private void setOnscreenKeyboardVisible(final boolean visible) {
        // Code comes from AndroidInput.setOnscreenKeyboardVisible except view is changed.
        handle.post(new Runnable() {
            public void run () {
                InputMethodManager manager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                if (visible) {
                    inputView.setFocusable(true);
                    inputView.setFocusableInTouchMode(true);
                    manager.showSoftInput(inputView, 0);
                } else {
                    manager.hideSoftInputFromWindow(inputView.getWindowToken(), 0);
                }
            }
        });
    }
}

如您所见,这并非易事。我也没有进行测试,所以可能还会缺少更多内容。

在那时,我宁愿建议您在github上提交问题并提出请求。 android图形视图实现是GLSurfaceView20(或GLSurfaceView20API18),并且它已覆盖onCreateInputConnection。您可以在Input界面中添加一个选项以禁用建议,并在每个后端上实施它。

如果对此有任何疑问,请随时询问。