前言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
}