如何在运行时更改软键盘高度?

时间:2013-11-19 23:16:34

标签: android keyboard

我正在设计一个软键盘,我想在运行时更改其高度,因为用户可以在横向和纵向模式之间进行选择。我知道如何在xml中更改键的高度,但我需要动态地进行。

我唯一想到的是从键盘继承并覆盖其 setKeysHeight int height ),但似乎无用,因为整个键盘停止响应我的点击和高度(虽然与以前不同)并不关心上述功能中的' height '。

任何想法/解决方法?

3 个答案:

答案 0 :(得分:15)

原始解决方案发布在https://stackoverflow.com/a/9695482/1241783,但没有解释,所以我在这里稍微扩展一下。

1)创建一个扩展Keyboard类的新类,该类覆盖getHeight()方法。

@Override
public int getHeight() {
   return getKeyHeight() * 3;
}

注意:这里的数字3是你的总行数,如果你的键盘有5行,则输入5.

如果每行的键盘行高不同,这里你需要自己计算并返回总高度(单位是以像素为单位,花了一些时间才算出它不是dp所以需要将dp转换为像素对于所有计算)例如:

@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而是设置为特定高度,则需要自己计算key.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());
}

答案 1 :(得分:0)

我在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;
   }
}

答案 2 :(得分:0)

Bruce的解决方案不再起作用。底部键在调整大小后停止响应。查看Keyboard.java:

href

因此getNearestKeys不会触发任何计算,computeNearestNeighbors()不会被多次调用(而且它是私有的,因此您不能直接调用它)。

我修改了Keyboard.Key类,而不是更改现有对象的大小:

    public int[] getNearestKeys(int x, int y) {
        if (mGridNeighbors == null) computeNearestNeighbors();

在onStartInput()中,每次都重新创建所有键盘对象:

     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
    }

仍然需要重写getHeight()以计算键盘总高度。

具有不同高度的键将非常棘手,因为您不仅需要计算总高度,还要计算每个按钮的y位置,并且它取决于前几行的高度。