Я хотел бы сделать изогнутую экранную клавиатуру для Android. Я изучил экранную клавиатуру и другие другие экранные клавиатуры в коде Google. Ничего, что я нашел, связано с формой клавиатуры, которая представляет собой нечто иное, чем прямоугольник. В идеале я хотел бы создать клавиатуру, состоящую из клавиш, распределенных по двум полукругам на противоположных сторонах экрана (т.е. Представьте, что вы держите планшет по сторонам и можете ударить по клавишам большими пальцами).
Из кода, который я рассмотрел, экранные клавиатуры создаются как виды (обычно расширяющие KeyboardView) и отображаются как непрерывная полоса в нижней части экрана. В качестве приближения к моей цели я попытался изменить код, который я нашел в коде google (dotdash-keyboard-android), чтобы только нарисовать его ключи в нижнем левом углу и оставить прозрачный нижний правый угол. Я смог переопределить onMeasure, чтобы повлиять на размеры представления (см. Ниже), но это только, кажется, изменяет позиции клавиш, а не позиции контейнера. Другими словами, в нижней части экрана есть черная полоска.
//Located within KeyboardView
@Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
this.setMeasuredDimension(200, 200);
}
Я хочу сделать то, что я хочу сделать? Есть ли более правильный термин для этого? Существуют ли проекты, которые я могу использовать в качестве примеров?
Я также попытался установить размеры представления с помощью this.setLayoutParams - но эти вызовы, похоже, не влияют. Я также попытался использовать this.getParent для доступа к родительскому представлению (если он существует) и изменить его размеры, но этот подход не работает (или, я просто делаю это неправильно). Любая помощь будет высоко оценена.
Спасибо
UPDATE: 12/21/2012 - Мне кажется, мне нужно переопределить метод родительского класса onDraw. Глядя на здесь, похоже, что метод KeyboardView onDraw рисует на холст, равный размеру экрана, используя следующий код:
final int width = Math.max(1, getWidth());
final int height = Math.max(1, getHeight());
mBuffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBuffer);
Я думаю, что могу переопределить onDraw и нарисовать все, что захочу на холсте.
UPDATE: 12/21/2012 - Я переопределил onDraw, и теперь ясно, что клавиатураView - это размеры, которые я устанавливаю для этого (200x200). Используя Hierarchyview, я вижу, что раскладка клавиатуры находится внутри рамки с идентификатором InputArea. Таким образом, горизонтальная полоса, заполняющая всю ширину, представляет собой этот кадр. Но я не создаю его - откуда он и как я могу изменить его размеры?
UPDATE: 12/22/2012 - после большего количества тестов кажется, что поведение (размеры) раскладки клавиатуры частично определяется действием, которое его вызывает. В браузере я получаю поведение, которое я описывал: высота окна браузера сокращается, чтобы разместить панель в нижней части экрана, которая удерживает клавиатуру, даже если ширина клавиатуры меньше ширины экран. В приложении календаря размер клавиатуры появляется, поскольку я установил его (как квадрат в нижнем левом углу), при этом календарь не изменился под ним. Таким образом, невозможно достичь моей цели в большинстве приложений, используя этот подход. Альтернативный подход может заключаться в том, чтобы служба IME создавала всплывающее окно или диалог. Одна из проблем заключается в том, что для всплывающих окон требуется родительское представление или привязка для присоединения, и я не думаю, что можно найти самый верхний вид из службы IME. Возможно, я могу создать прозрачный вид над текущей деятельностью и разместить всплывающее окно поверх этого?
ОБНОВЛЕНИЕ: 12/23/2012 - Прогресс. Я выяснил, как отображать всплывающее окно с клавиатуры IME. Следующий шаг - выяснить, как сделать всплывающие окна немного круглыми/органическими. Вот скриншот того, что я сделал, за которым следовал источник.
Источник. Следующий метод относится к классу IME службы и вызывается режимом child (of the service) onMeasure, чтобы всплывающие окна открывались одновременно с рисованием клавиатуры. Я установил размеры клавиатуры в 1x1, чтобы она не была видна. Операторы журнала помогут мне разобраться, как расположить всплывающие окна.
public void initiatePopupWindow()
{
try {
WindowManager wm = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
DisplayMetrics dm = new DisplayMetrics();
display.getMetrics(dm);
//display.getSize(p);
Log.i("dotdashkeyboard","initiatePopupWindow (from IME service)");
LayoutInflater inflater = (LayoutInflater) this.getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layoutLeft = inflater.inflate(R.layout.popup_layout_left,null);
View layoutRight = inflater.inflate(R.layout.popup_layout_right, null);
// create a 300px width and 470px height PopupWindow
int popupHeight = 300;
int popupWidth = 200;
if (popUpLeft == null) popUpLeft = new PopupWindow(layoutLeft, popupWidth, popupHeight, false);
if (popUpRight == null) popUpRight = new PopupWindow(layoutRight, popupWidth, popupHeight, false);
int ypos = 0;
int xposRight = 0;
if (display.getRotation() == Surface.ROTATION_0) {
ypos = -(dm.heightPixels / 2 + popupHeight/2);
xposRight = (dm.widthPixels - popupWidth);
Log.i("dotdashkeyboard","test rotation=normal");
} else if (display.getRotation() == Surface.ROTATION_90) {
ypos = -(dm.heightPixels / 2 + popupHeight/2)/2;
xposRight = (dm.widthPixels - popupWidth)*2-popupWidth;
Log.i("dotdashkeyboard","test rotation=90-degrees");
} else {
Log.i("dotdashkeyboard","test rotation=unknown=" + display.getRotation());
}
popUpLeft.showAtLocation(inputView, Gravity.NO_GRAVITY, 0, ypos);
popUpRight.showAtLocation(inputView, Gravity.NO_GRAVITY, xposRight, ypos);
Log.i("dotdashkeyboard","test created popup at ypos="+ypos + " xposRight=" + xposRight);
Log.i("dotdashkeyboard","test screenWidth=" + dm.widthPixels + " screenHeight=" + dm.heightPixels);
Button cancelButton = (Button) layoutLeft.findViewById(R.id.popup_cancel_button);
//cancelButton.setOnClickListener(inputView.cancel_button_click_listener);
cancelButton.setOnClickListener(cancel_button_click_listener);
} catch (Exception e) {
e.printStackTrace();
}
}