2013-11-19 5 views
7

Я разрабатываю мягкую клавиатуру, и я хочу изменить ее высоту во время выполнения, когда пользователь выбирает между пейзажным и портретным режимами. Я знаю, как изменить высоту ключа в xml, но мне нужно сделать это динамически.Как изменить высоту мягкой клавиатуры во время выполнения?

Единственное, что пришло мне на ум был подкласс от Keyboard и переопределить его setKeysHeight (INTвысота), но мне кажется бесполезным, так как вся клавиатура перестала отвечать на мои клики и высоты (хотя и отличается от ранее) не волнует «высота» в вышеупомянутой функции.

Любая идея/обходной путь?

+0

я борюсь с этим тоже. Вызов setKeysHeight и setKeysWidth, похоже, ничего не делает. Ответ на http://stackoverflow.com/a/9695482/1241783, похоже, работает частично, но я до сих пор не могу изменить высоту клавиатуры! – Bruce

+0

В итоге я определил отдельные макеты для каждой клавиатуры, в которой я нуждался, и затем, при необходимости, установил KeyboardView.setKeyboard (...). Таким образом, каждая клавиатура, требующая разной высоты ключа, имела отдельный объект Keyboard. –

+0

Не уверен, что вам все еще нужно, но я вроде как получил его работу, набрав ответ сейчас – Bruce

ответ

14

Оригинальное решение опубликовано: https://stackoverflow.com/a/9695482/1241783, но оно не содержит пояснений, поэтому здесь я немного расширяю его.

1) Создайте новый класс, который расширяет класс клавиатуры, который переопределяет метод 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, но устанавливается на определенную высоту, а не не использовать, вам необходимо вычислить key.y положение самостоятельно.

Если высота каждой строки клавиатуры различна для каждой строки, вам может потребоваться проверить ключи, определить принадлежащую ей строку и установить высоту для коррекции значения, если ключи не будут перекрывать друг друга. Также сохраните высоту строки в частной переменной, которая будет использоваться в getHeight() выше. PS: При определенной конфигурации я не мог нажать клавиши нижней строки после изменения высоты клавиатуры, и я обнаружил, что вызов getNearestKeys() исправляет это, хотя я не совсем уверен, почему.

Примечание: key.y - это позиция y, координата 0 начинается с верхней части клавиатуры и уменьшается при увеличении значения. например Координата 100 точек до 100 пикселей от верхней части клавиатуры :)

3) Последний шаг - вызвать changeKeyHeight в вашем основном классе, который расширяет InputMethodService. Сделайте это внутри (переопределите) 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); 
} 

Ура!

Дополнительно: Если вам нужен дп конвертер пикселей, вот код:

private int convertDpToPx(int dp) 
{ 
    return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics()); 
} 
+0

, который отлично работал :) – user2469133

+0

спасибо. Как я могу получить высоту каждой строки. Я использую разную высоту для разных строк – myatmins

+0

Что такое mInputView в этом? – John

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; 
    } 
} 
Смежные вопросы