我想到的唯一方法是从Keyboard类进行子类化,并覆盖其setKeysHeight(int height)方法,但似乎这样做没有用,整个键盘都无法响应我的点击,而且高度(虽然与以前不同)也不关心上述函数中的'height'参数。
有什么想法或解决方法吗?
原始解决方案发布在https://stackoverflow.com/a/9695482/1241783,但没有解释,所以我在这里稍微扩展一下。
1)创建一个新类,继承Keyboard类并重写getHeight()方法。
@Override
public int getHeight() {
return getKeyHeight() * 3;
}
注意:这里的数字3是您的总行数,如果您的键盘有5行,请填写5。@Override
public int getHeight() {
return row1Height + row2Height + row3Height + row4Height + row5Height;
}
2)在同一类中创建一个新的公共函数。
public void changeKeyHeight(double height_modifier)
{
int height = 0;
for(Keyboard.Key key : getKeys()) {
key.height *= height_modifier;
key.y *= height_modifier;
height = key.height;
}
setKeyHeight(height);
getNearestKeys(0, 0); //somehow adding this fixed a weird bug where bottom row keys could not be pressed if keyboard height is too tall.. from the Keyboard source code seems like calling this will recalculate some values used in keypress detection calculation
}
如果您没有使用height_modifier,而是设置了特定的高度,则需要自己计算关键字的y位置。
如果您的键盘每行的高度不同,则可能需要检查键并确定它所属的行,并将高度设置为正确的值,否则键将重叠。还要将行高存储在私有变量中,以便在上面的getHeight()中使用。PS:在某些配置上,我在更改键盘高度后无法按下底部行键,并且我发现调用getNearestKeys()可以解决这个问题,尽管我不确定原因。
注意:key.y是键的y位置,坐标0从键盘顶部开始,随着值的增加向下移动。例如,坐标100指向距键盘顶部100像素的位置:)
3)最后一步是在扩展InputMethodService的主类中调用changeKeyHeight。在onStartInputView()内执行此操作(覆盖它),因为在更改高度(通过偏好或其他方式)后应重新绘制键盘。
如果您正在查看Android软键盘示例项目,则会像这样:
@Override public void onStartInputView(EditorInfo attribute, boolean restarting) {
super.onStartInputView(attribute, restarting);
// Change the key height here dynamically after getting your value from shared preference or something
mCurKeyboard.changeKeyHeight(1.5);
// Apply the selected keyboard to the input view.
mInputView.setKeyboard(mCurKeyboard);
mInputView.closing();
final InputMethodSubtype subtype = mInputMethodManager.getCurrentInputMethodSubtype();
mInputView.setSubtypeOnSpaceKey(subtype);
}
干杯!
额外提示:如果你需要一个dp到像素的转换器,这是代码:
private int convertDpToPx(int dp)
{
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics());
}
我在Android 6上使用以下代码:
private void adjustKeyboardKeyHeight (MyKeyboard keyboard, int newKeyHeight) {
int oldKeyHeight = keyboard.getKeyHeight();
int verticalGap = keyboard.getVerticalGap();
int rows = 0;
for (Keyboard.Key key : keyboard.getKeys()) {
key.height = newKeyHeight;
int row = (key.y + verticalGap) / (oldKeyHeight + verticalGap);
key.y = row * newKeyHeight + (row - 1) * verticalGap;
rows = Math.max(rows, row + 1);
}
keyboard.setHeight(rows * newKeyHeight + (rows - 1) * verticalGap);
}
private static class MyKeyboard extends Keyboard {
private int height;
MyKeyboard (Context context, int xmlLayoutResId) {
super(context, xmlLayoutResId);
height = super.getHeight();
}
@Override public int getKeyHeight() {
return super.getKeyHeight();
}
@Override public int getVerticalGap() {
return super.getVerticalGap();
}
public void setHeight (int newHeight) {
height = newHeight;
}
@Override public int getHeight() {
return height;
}
}
public int[] getNearestKeys(int x, int y) {
if (mGridNeighbors == null) computeNearestNeighbors();
因此,getNearestKeys不会触发任何计算,computeNearestNeighbors()也不会被调用超过一次(而且它是私有的,所以你不能直接调用它)。
我没有改变现有对象中的大小,而是修改了Keyboard.Key类:
public class FTKey extends Keyboard.Key {
FTKey(Resources res, Keyboard.Row parent, int x, int y, XmlResourceParser parser) {
super(res, parent, x, y, parser);
this.height = (int) (height * FTPref.yScale);
this.y = this.height * FTPref.yScale; // This works only if all rows of the same height
}
FTPref.yScale = 0.7f;
mEnglishKeyboard = new FTKeyboard(this ...
mRussianKeyboard = new FTKeyboard(this ...
仍需覆盖getHeight()方法以计算总键盘高度。
如果要使用不同高度的按键,这将变得棘手,因为你不仅需要计算总高度,还需要计算每个按钮的y位置,并且这取决于前几行的高度。