Change native keyboard's layout on iOS and Android?

Hi,

I’m trying to change soft keyboard’s type to fill in text as email as well as change keyboard’s return key.

This is my AS3 code where i’ve used StageText:

   const options:StageTextInitOptions = new StageTextInitOptions(false);
   input = new StageText(options);
   input.returnKeyLabel = ReturnKeyLabel.DONE;
   input.softKeyboardType = SoftKeyboardType.EMAIL;

Is there a way to do the same in openfl’s TextField?

Thanks in advance!

I have looked into this (extensively) on Android – there seems to be no method of changing the keyboard type, unless the keyboard is triggered by an Android UI input element. You CANNOT change it directly from C++, or even from a straight Java API. This is very frustrating.

There are dirty, horrible hacks with hidden UI input fields that can be used to work around this – none I felt comfortable attempting. This could change, though, with some change in the Android API. I’m interested if there is such a thing?

For iOS, I’m not sure – the lack of Android support stunted researching further

I wonder how Unity deals with it. Changing keyboard layout works great there.

Well, I’ve managed to get it to work :slight_smile: Unfortunately singmajesty was right and other keyboard types cannot be used without native UI elements :frowning:
Here’s the code, it’s quite raw and it would be best to create an extension out of it, but I don’t have much time now :confused:

MainActivity.java:

public static MainActivity mainActivity;
    private static EditText input;
    private static FrameLayout targetFrame;
    private static HaxeObject callback;
    private static HaxeObject tf;

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

        LayoutParams lParamsMW = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT, 1);

        input = new EditText(this);
        input.setLayoutParams(lParamsMW);
        RelativeLayout wrapView = wrapView();
        ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        addContentView(wrapView, params);
        targetFrame.addView(input);
        input.addTextChangedListener(new TextWatcher()
        {
            @Override
            public void afterTextChanged(Editable s)
            {
                Extension.callbackHandler.post(new Runnable() { public void run()
                {
                    callback.call("onTextEdit", new Object[] {input.getText().toString(), tf});
                }});
            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {}

        });
	}
    private RelativeLayout wrapView()
    {
        RelativeLayout parentLayout = new RelativeLayout(getApplicationContext());
        parentLayout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        targetFrame = new FrameLayout (getApplicationContext());
        RelativeLayout.LayoutParams targetFrameParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
        parentLayout.addView(targetFrame, targetFrameParams);
        parentLayout.setVisibility(View.GONE);
        return parentLayout;
    }
    public static void showKeyboard(final HaxeObject _callback, final HaxeObject _tf, final String initText)
    {
        callback = _callback;
        tf = _tf;
        Extension.callbackHandler.post(new Runnable() { public void run()
        {
            input.setText(initText);
            input.setSelection(input.getText().length());
            input.setInputType(InputType.TYPE_CLASS_NUMBER); //change to desired soft keyboard type
            input.requestFocusFromTouch();
            mainActivity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
            InputMethodManager imm = (InputMethodManager) mainActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.showSoftInput(input, 0);

        }});
    }

Somewhere in haxe:

 private function init():Void
    {
        tf = new TextField();
        addChild(tf);
        tf.border = true;
        tf.borderColor = 0xFFFFFF;
        tf.width = stage.stageWidth;
        tf.height = 100;
        tf.textColor = 0xFFFFFF;
        tf.text = "test";
        tf.y = 50;
        tf.addEventListener(MouseEvent.MOUSE_DOWN, function(e:MouseEvent):Void
        {
            var showKeyboard:Dynamic = JNI.createStaticMethod("my.test.package.MainActivity", "showKeyboard", '(' + 'Lorg/haxe/lime/HaxeObject;' + 'Lorg/haxe/lime/HaxeObject;' + 'Ljava/lang/String;' + ')' + "V");
            showKeyboard(this, tf, tf.text);
        });
    }
    private function onTextEdit(text:String, textfield:TextField)
    {
        textfield.text = text;
    }

Even the “Swype” works :slight_smile:
Btw. I’ve tested this only on legacy, I’ll try to create a proper extension out of it someday

1 Like