前言1:在J2ME中,如果使用低级界面技术绘制输入框,那么用户的输入完全由程序来处理。这篇文章,详细的分析了怎么处理用户的输入。
前言2:本方案中,没有涉及汉字的输入,如果要输入汉字,需要借助于第三方包,自己处理汉字输入,太花时间,单干不太现实。
前言3:本方案可以输入数字,大写字母,小写字母,一些简单的符号。其中#切换输入状态(在数字,大写字母,小写字母之间切换),*输入符号(暂时只支持_/@*#,其他的读者可以自己添加)。
在J2ME中,处理用户按键的入口方法是keyPressed,而标准的手机键盘,我们可以获取到0-9,*,#这些输入。依靠这两点,我们开始用户输入的设计。
第一步:把用户的按键转化为程序里面的常量,方便后面的处理(当然,这一步不是必须的,但是加上以后,逻辑更加清楚)
private int pressKeyAction;//记录按键的临时变量
// 键盘鼠标事件 public boolean[] listKeys = new boolean[GameConst.KEY_COUNT]; //GameConst.KEY_COUNT是常量,数值为21,如果你使用本段代码,可以在这里直接写21,而且这个数值是后面程序会用到的。
protected void keyPressed(int i) { super.keyPressed(i); pressKeyAction = getGameAction(i); if (-pressKeyAction >= GameConst.KEY_1) {//处理数字输入 listKeys[-pressKeyAction] = true; return; } switch (pressKeyAction) { case GameCanvas.UP: listKeys[GameConst.KEY_UP] = true; break; case GameCanvas.DOWN: listKeys[GameConst.KEY_DOWN] = true; break; case GameCanvas.LEFT: listKeys[GameConst.KEY_LEFT] = true; break; case GameCanvas.RIGHT: listKeys[GameConst.KEY_RIGHT] = true; break; case GameCanvas.FIRE: listKeys[GameConst.KEY_FIRE] = true; break; case -1: listKeys[GameConst.KEY_LEFTSOFT] = true; break; case -2: listKeys[GameConst.KEY_RIGHTSOFT] = true; break; case -3: listKeys[GameConst.KEY_SHORTCUT] = true; break; case -4: listKeys[GameConst.KEY_ZERO] = true; break; case -5: listKeys[GameConst.KEY_STAR] = true; break; case -6: listKeys[GameConst.KEY_POUND] = true; break; } }
通过这一步,我们就把用户输入信息存放在了一个boolean数组之中,如果用户输入1,那么数组中保存1的那一位,就是true。
这里补充一下程序中可能用到的数字,当然,我是写在GameConst中,以常量的方式处理:
// @Key List int KEY_COUNT = 21; int KEY_UP = 0; int KEY_DOWN = 1; int KEY_LEFT = 2; int KEY_RIGHT = 3; int KEY_FIRE = 4; int KEY_LEFTSOFT = 5; int KEY_RIGHTSOFT = 6; int KEY_SHORTCUT = 7; int KEY_ZERO = 8; int KEY_STAR = 9; int KEY_POUND = 10; int KEY_1 = 11; int KEY_2 = 12; int KEY_3 = 13; int KEY_4 = 14; int KEY_5 = 15; int KEY_6 = 16; int KEY_7 = 17; int KEY_8 = 18; int KEY_9 = 19; int KEY_DEL = 20;
下面,我们就可以根据不同的输入,做不同的处理了:
public void onKeyPressed(boolean[] listKeys) { if (listKeys[GameConst.KEY_1]) { onKeyPressedDone(0); } else if (listKeys[GameConst.KEY_2]) { onKeyPressedDone(1); } else if (listKeys[GameConst.KEY_3]) { onKeyPressedDone(2); } else if (listKeys[GameConst.KEY_4]) { onKeyPressedDone(3); } else if (listKeys[GameConst.KEY_5]) { onKeyPressedDone(4); } else if (listKeys[GameConst.KEY_6]) { onKeyPressedDone(5); } else if (listKeys[GameConst.KEY_7]) { onKeyPressedDone(6); } else if (listKeys[GameConst.KEY_8]) { onKeyPressedDone(7); } else if (listKeys[GameConst.KEY_9]) { onKeyPressedDone(8); } else if (listKeys[GameConst.KEY_ZERO]) { onKeyPressedDone(10); } else if (listKeys[GameConst.KEY_STAR]) { if (key_type == 0 || key_type == 1) { } else { onKeyPressedDone(9); } } else if (listKeys[GameConst.KEY_POUND]) { key_type = (key_type + 1) % 3; onKeyPressedDone(-10);// 这里是重置键盘状态 } else if (listKeys[GameConst.KEY_DOWN]) { //这个地方,根据自己的业务逻辑处理,对应的按键是向下键 } else if (listKeys[GameConst.KEY_UP]) { //这个地方,根据自己的业务逻辑处理,对应的按键是向上键 } else if (listKeys[GameConst.KEY_LEFT]) { //这个地方,根据自己的业务逻辑处理,对应的按键是向左键 } else if (listKeys[GameConst.KEY_RIGHTSOFT]) { //这个地方,根据自己的业务逻辑处理,对应的按键是右软键 } //当然,这后面还可以处理向右键等,自己添加 }
上段代码中用到了一些变量,这里补充说明:
private int key_type = 0;//记录输入类型,有三类:数字,大写字母,小写字母
最后就是比较复杂的onKeyPressedDone了,它真正的处理了按键的逻辑:
private String[] alphas0 = { "_/@*#", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz", "切换", "0", "退格" }; private String[] alphas1 = { "_/@*#", "ABC", "DEF", "GHI", "JKL", "MNO", "PQRS", "TUV", "WXYZ", "切换", "0", "退格" }; private String[] alphas2 = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "*", "0", "#" }; /** * 上一次点击的按钮 */ private int old_digit = -1; /** * 当前按钮被点击的次数 */ private int single_digit = 0; private long inputTime = 0L; private int inputWait = 700; private void onKeyPressedDone(int digit) { if (digit == -10) {//这里重置状态 inputTime = System.currentTimeMillis(); old_digit = digit; return; } switch (key_type) { case 0: {// 小写字母 if (old_digit == digit) {//两次输入一样,意思就是对一个键连续点击了两次 if (System.currentTimeMillis() - inputTime <= inputWait) {//连续两次的输入时间小于等待时间,认为是想输入同一个位置上的下一个字母 if (digit == 0 || digit == 6 || digit == 8) { single_digit = (single_digit + 1) % 4; } else { single_digit = (single_digit + 1) % 3; } } else {//连续两次的输入时间大于等待时间,认为是想输入同一个位置字母两次 single_digit = 0; } } else {//连续两次的输入不同 single_digit = 0; } System.out.println(alphas0[digit].charAt(single_digit));//输出的内容,是你想要的 break; } case 1: {// 大写字母 if (old_digit == digit) { if (System.currentTimeMillis() - inputTime < inputWait) { if (digit == 0 || digit == 6 || digit == 8) { single_digit = (single_digit + 1) % 4; } else { single_digit = (single_digit + 1) % 3; } } else { single_digit = 0; } } else { single_digit = 0; } System.out.println(alphas1[digit].charAt(single_digit));//输出的内容,是你想要的 break; } case 2: {// 数字 System.out.println(alphas2[digit]);//输出的内容,是你想要的 break; } default: break; } inputTime = System.currentTimeMillis();//在输入处理结束以后,重置inputTime old_digit = digit;//在输入处理结束以后,重置old_digit }