Подтвердить что ты не робот

Как сделать изогнутую экранную клавиатуру для Android

Я хотел бы сделать изогнутую экранную клавиатуру для 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. Следующий шаг - выяснить, как сделать всплывающие окна немного круглыми/органическими. Вот скриншот того, что я сделал, за которым следовал источник. Emulator screenshot of keyboard

Источник. Следующий метод относится к классу 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();
    }
}
4b9b3361

Ответ 1

Ты, кажется, на правильном пути. Как вы отметили, большинство действий сократят их представления, чтобы предоставить пространство для окна клавиатуры, поэтому, если вы хотите, чтобы вызывающая активность заполняла экран, вам нужно использовать дополнительное окно, например PopupWindow. Вы можете установить размеры вашего основного окна на 0x0.

Вы пробовали позвонить popUpLeft.setBackgroundDrawable(null)/popUpRight.setBackgroundDrawable(null)? Это должно удалить полупрозрачный фон и показать только то, что вы нарисуете сверху.