The first way is to develop own custom keyboard. This is used to reach graphically perfect keyboard that match game design. Graphically perfect but funcional limited. To enter some non-ASCII character is not possible or it takes additional effort to implement a support national characters. Also switching keyboard’s layout can be very limited rather missing generally (no layout for numerics, special characters, etc). To implement custom keyboard you need to create set of buttons, that emulate a keyboard events:
include "lib://game2d/base/gameControl.ms" class KeyButton: TextButton
{ var smallPaint = null; // overwritten
function beforeInit()
{
super.beforeInit(); if (KeyButton.smallPaint == null) {
var p = new Paint();
p.textSize = System.height / 40;
p.color = 0xffffff00;
p.typeface = Typeface.fromName("Mail Ray Stuff", #normal);
KeyButton.smallPaint = p;
}
} // overwritten
function draw(canvas)
{
canvas.save(#matrix);
canvas.scale(this._scale, this._scale);
canvas.translate(-this._anchorX, -this._anchorY)
if (typeof this._text == #string) {
canvas.drawText(this._text, this._x, this._y + this._height, TextButton.paint);
} else {
canvas.drawText(this._text.toString(), this._x, this._y + this._height, KeyButton.smallPaint);
}
canvas.restore();
} // overwritten
property text(v)
{
get { return this._text; }
set {
var (dw, dh) = typeof v == #string ? TextButton.paint.measureText(v) : KeyButton.smallPaint.measureText(v.toString());
this._width = dw;
this._height = dh;
this._anchorX = this._width / 2;
this._anchorY = this._height / 2;
}
} } class CustomKbControl : GameControl
{
var gap = System.width / 13; // overwritten
function init()
{
super.init(); this._bgPaint = new Paint();
this._bgPaint.color = 0x55000000; this._map = this.options.map ||
[["q", "w", "e", "r", "t", "y", "u", "i", "o", "p"],
["a", "s", "d", "f", "g", "h", "j", "k", "l", #backspace],
["z", "x", "c", "v", "b", "n", "m", #enter],
[#space]]; this._width = this.options.width || System.width / 10 * 9;
this._height = this.options.height || System.height / 10 * 3; this._anchorX = this._width / 2;
this._anchorY = this._height / 2; this._buttons = [];
this._build();
} // overwritten
function draw(canvas)
{
canvas.save(#matrix);
canvas.translate(this._x, this._y);
canvas.scale(this._scale, this._scale);
canvas.translate(-this._anchorX, -this._anchorY) canvas.drawRect(0, 0, this.width, this.height, this._bgPaint); for(var b in this._buttons)
b.draw(canvas); canvas.restore();
} // overwritten
function pointerPressed(x, y)
{
super.pointerPressed(x, y);
x += -this._x + this._anchorX;
y += -this._y + this._anchorY;
for (var b in this._buttons)
if (b.intersectsPoint(x, y))
b.pointerPressed(x, y);
} // overwritten
function pointerReleased(x, y)
{
super.pointerReleased(x, y);
x += -this._x + this._anchorX;
y += -this._y + this._anchorY;
for (var b in this._buttons)
if (b.intersectsPoint(x, y))
b.pointerReleased(x, y);
} property width(v)
{
get {
return this._width;
}
} property height(v)
{
get {
return this._height;
}
} property onKey(v)
{
get return this._onKeyHandler;
set
{
if(typeof(v) != #function || v == null)
throw new InvalidArgument("[CustomKbControl.onKey] Instance of function expected");
this._onKeyHandler = v;
}
} function _build()
{
for (var r = 0; r < this._map.length; r++) {
var cols = this._map[r].length;
for (var c = 0; c < cols; c++) {
var chr = this._map[r][c];
var x = CustomKbControl.gap/2 + c * CustomKbControl.gap;
var y = CustomKbControl.gap + r * (4*CustomKbControl.gap/3);
switch (r) {
case 0: x += System.width / 18; break;
case 1: x += System.width / 30; break;
case 2: x += System.width / 10; break;
case 3: x += System.width / 3; break;
}
if (typeof chr == #symbol) x += CustomKbControl.gap/2;
var button = new KeyButton({text:chr, x:x, y:y});
button.key = chr;
button.onClick = function(sender) {
var self = this super;
if (typeof self.onKey == #function)
self.onKey(self, sender.key);
}
this._buttons.push(button);
}
}
} }

Usage of built-in keyboard appears to be a better way. Moscrif allows you to use it very simple way. System.requestKeyboard is designed to invoke system (build-in, native) keyboard:
include "lib://game2d/scene.ms" class SystemKbScene : Scene
{
// overwritten
function init()
{
super.init(); this._paint = new Paint();
this._paint.color = 0xff00fffff;
this._paint.textSize = System.height/20;
this._paint.typeface = Typeface.fromName("Mail Ray Stuff", #normal);
this._playerName = "player"; this._quit = new TextButton({name:"btnQuit", text:"back", y:System.height/10*9, x:System.width/2});
this._quit.onClick = function(sender) { game.pop(); }
this.add(this._quit); game.onKeyReleased = function(sender, key)
{
this super._keyboardHandler(key);
} game.onChar = function(sender, key)
{
this super._keyboardHandler(key);
} } // overwritten
function draw(canvas)
{
super.draw(canvas); canvas.drawText("Name :", 50, 100, this._paint);
canvas.drawText(this._playerName, System.width/2, 100, this._paint);
} // overwritten
function pointerReleased(x, y)
{
super.pointerReleased(x, y);
if (!this._quit.intersectsPoint(x, y))
this._keyboard ? this._hideKeyboard() : this._showKeyboard();
} function _keyboardHandler(key)
{
if (key == #backspace)
this._playerName = this._playerName.substr(0, this._playerName.length - 1);
else if (key == #enter)
this._hideKeyboard();
else if (typeof key == #string)
this._playerName += key;
} function _showKeyboard()
{
this._keyboard = true;
System.requestKeyboard(function(sender, key) {
this super._keyboardHandler(key);
});
}
function _hideKeyboard()
{
this._keyboard = false;
System.hideKeyboard();
} }

On the left picture there is screenshot from iPhone. On the right picture there is taken photo of Amazon Kindle Fire.
In short, you can use both custom and native (system) keyboards in your own games.
Source code: GameKeyboard.zip