楼主,我已经试着实现了一把,但是现在还有个疑问,现在的焦点是在按键d上,现在按下方向键,该怎么走到它相邻的焦点上?现在我的写法是在 SoftKeyboard.java 这个类里面根据当前按键的所在行和所在列来计算,不过这样做有很多BUG,要做很多特殊处理,比如从第4行的空格上移时,下一焦点该走 c 还是 v 还是 b 等。我实在不知道怎么解决这个问题,所以还请楼主提示一下,谢谢!
/**
* 移动焦点到下一焦点
* @param originX 当前焦点所在列
* @param originY 当前焦点所在行
* @param keyCode 按键码
* @return 如果没有越过边界,则返回true
*/
//TODO: 优化找焦点
public boolean moveToKey(int originX, int originY, int keyCode, KeyCoordinates keyCoordinates) {
int nextX = 0;
int nextY = 0;
//最多4行。mKeyRows.size()返回7行,暂时写死4行这样解决
int rowCount = 4;//mKeyRows.size();
if(originY >= rowCount) {
Log.e(TAG, "moveToKey error. originY = " + originY + " larger than mKeyRows.size() = " + rowCount);
return false;
}
KeyRow row = mKeyRows.get(originY);
int colCount = row.mSoftKeys.size();
if(originX >= colCount) {
Log.e(TAG, "moveToKey error. originX = " + originX + " larger than row.mSoftKeys.size() = " + colCount);
return false;
}
if(originX == 0 && originY == 0 && keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
nextY = rowCount - 1;
nextX = mKeyRows.get(rowCount - 1).mSoftKeys.size() - 1;
} else if(originX == colCount - 1 && originY == rowCount - 1 && keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
nextY = 0;
nextX = 0;
} else {
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_LEFT:
if(originX == 0) {
nextX = mKeyRows.get(originY - 1).mSoftKeys.size() - 1;
nextY = originY - 1;
} else {
nextX = originX - 1;
nextY = originY;
}
break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
if(originX == colCount - 1) {
nextX = 0;
nextY = originY + 1;
} else {
nextX = originX + 1;
nextY = originY;
}
break;
case KeyEvent.KEYCODE_DPAD_UP:
//如果焦点已经在第一行,则焦点保持不变
if(originY == 0) {
nextX = originX;
nextY = originY;
} else {
//如果焦点在某一行最后一个,则上移时也将保持在上一行最后一个
if(originX == colCount - 1) {
nextX = mKeyRows.get(originY - 1).mSoftKeys.size() - 1;
nextY = originY - 1;
//如果焦点在某一行第一个,则上移时也将保持在上一行第一个
} else if(originX == 0) {
nextX = 0;
nextY = originY - 1;
} else if(originY == 3 && originX == 2) {
nextX = 4;
nextY = 2;
} else if(originY == 3 && originX == 3) {
nextX = 6;
nextY = 2;
} else {
nextX = originX;
nextY = originY - 1;
}
}
break;
case KeyEvent.KEYCODE_DPAD_DOWN:
//如果焦点已经在最后一行,则焦点保持不变
if(originY == rowCount - 1) {
nextX = originX;
nextY = originY;
} else {
//如果焦点在某一行最后一个,则下移时也将保持在下一行最后一个
if(originX == colCount - 1) {
nextX = mKeyRows.get(originY - 1).mSoftKeys.size() - 1;
nextY = originY + 1;
//如果焦点在某一行第一个,则下移时也将保持在下一行第一个
} else if(originX == 0) {
nextX = 0;
nextY = originY + 1;
} else if(originY == 2 && (originX == 1 || originX == 2)) {
nextX = 1;
nextY = 3;
} else if(originY == 2 && (originX == 3 || originX == 4 || originX == 5)) {
nextX = 2;
nextY = 3;
} else if(originY == 2 && (originX == 6 || originX == 7)) {
nextX = 3;
nextY = 3;
} else {
nextX = originX;
nextY = originY + 1;
}
}
break;
}
}
keyCoordinates.setX(nextX);
keyCoordinates.setY(nextY);
return true;
}