Android: KeyboardView не отображается над EditText

Я пытаюсь EditText и возможность отображать клавиатуру в нижней части экрана, когда пользователь нажимает EditText, Я знаю о InputMethodService и пример SoftKeyboard, но я не могу использовать его таким образом, поскольку моя клавиатура должна быть доступна только для этого EditText,

Кроме того, должно быть контекстное меню, но это не является частью этого вопроса (я думаю).

Я прочитал много фрагментов кода, но во многих случаях они содержат методы, которые больше не доступны (например, getViewInflate()) или написаны в контексте, который я не понимаю или не могу перевести на мой код (учтите, что я новичок в отношении Android).

В большинстве попыток я терплю неудачу с этим исключением, когда я нажимаю EditText:

java.lang.IllegalArgumentException: width and height must be > 0

сопровождаемый следом стека, который не содержит ни одного из моих классов. Как вы можете видеть в коде ниже, все размеры установлены.

Ниже вы видите текущее состояние кода (я удалил часть кода и надеюсь, что он по-прежнему имеет смысл). Я также пытался использовать то, что внутри handler.post() в главном потоке используйте закомментированные вещи вместо handler.post()...

Что не ниже, это попытка использовать RelativeLayout с EditText и KeyboardView в одном макете-XML. Было другое исключение, что-то вроде "неверный тип 0x12" или что-то подобное при создании макета.

Это просто не работает, или я просто не знаю, как это сделать. Может кто-нибудь, пожалуйста, проведите меня через это? Пожалуйста, дайте мне знать, если что-то не хватает.

main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
  <EditText
    android:id="@+id/field_input"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:inputType="textMultiLine|textImeMultiLine"
    android:typeface="monospace"
    android:gravity="top|left"
    android:maxLength="255"
    />
</LinearLayout>

keyboard.xml:

<?xml version="1.0" encoding="utf-8"?>
<com.messenger.keyboard.LatinKeyboardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/keyboard"
    android:layout_alignParentBottom="true"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    />

LatinKeyboardView.java:

import android.inputmethodservice.KeyboardView;

public class LatinKeyboardView extends KeyboardView {
    :
}

EditorActivity.java

import android.app.Activity;

public class EditorActivity extends Activity {
    private View keyboardLayout;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        final EditText inputField;

        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        keyboardLayout = (View)getLayoutInflater().inflate(R.layout.keyboard, null, false);
        inputField = (EditText)findViewById(R.id.field_input);
        registerForContextMenu(inputField);

        inputField.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Handler handler = new Handler(Looper.getMainLooper());

                    handler.post(new Runnable() {
                            @Override
                            public void run() {
                                LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                                //PopupWindow pw = new PopupWindow(inflater.inflate(R.layout.input, null, false), 100, 100, true);
                                PopupWindow pw = new PopupWindow(keyboardLayout, 100, 100, true);

                                pw.showAtLocation(findViewById(R.id.field_input), Gravity.CENTER, 0, 0);
                            }
                        });

/*
                    if (keyboardLayout.getVisibility() == View.GONE) {
                        // Show Media Player
                        TranslateAnimation mAnimUp = 
                            new TranslateAnimation(
                                    Animation.RELATIVE_TO_SELF, 0,
                                    Animation.RELATIVE_TO_SELF, 0,
                                    Animation.RELATIVE_TO_SELF, -keyboardLayout.getHeight(),
                                    Animation.RELATIVE_TO_SELF, 0);

                        mAnimUp.setStartOffset(500);
                        mAnimUp.setDuration(500);

                        keyboardLayout.setVisibility(View.VISIBLE);
                        keyboardLayout.setAnimation(mAnimUp);
                    }
*/
                }
            });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        :
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        :
    }

    @Override
    public boolean onOptionsItemSelected(final MenuItem item) {
        :
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
        :
    }
}

2 ответа

Решение

В настоящее время я заново изобретаю свой подход, так как считаю, что не сломал InputMethodService достаточно, чтобы это работало без самого себя. Другими словами, я выбросил образец и начал с нуля, чтобы заставить работать макет (теперь это один макет вместо двух), а затем добавил код из примера для правильной обработки входных данных.

После дальнейших исследований я нашел действительно полезный вопрос о программной клавиатуре для конкретного приложения. Если вы столкнетесь с моей ситуацией, посмотрите там.

После нескольких часов "исследований и попыток" я наконец понял свою ошибку, которая, похоже, была "sjngm". Для рендеринга виртуальной клавиатуры необходимо

  1. объявите представление, надувая XML-файл макета или объявив в строке KeyboardView (так же, как вы сделали бы это для другого View).
  2. И что здесь было забыто: получить KeyboardView с findViewById() и позвонить на это:keyboardViewInstance.setKeyboard(new Keyboard(...) );

Вот и все. Вы сможете увидеть вашу клавиатуру на экране! Конечно, вам нужно либо создать свой собственный класс Keyboard, либо использовать существующий с файлом ресурсов xml, определяющим ваши клавиши клавиатуры (res/xml/keyboard.xml),

Другие вопросы по тегам