I'm trying to have an EditText
and the possibility to display a keyboard at the bottom of the screen when the user taps the EditText
. I'm aware of the InputMethodService
and the SoftKeyboard example, but I can't use it in that fashion as my keyboard should only be available to this very EditText
.
Furthermore, there should be a context menu, but that's not part of this question (I think).
I've read plenty of code fragments, but in many cases they contain methods that aren't available anymore (i.e., getViewInflate()
) or are written in a context that I don't understand or can't translate into my code (mind that I'm a newbie regarding Android).
In most attempts I fail with this exception when I tap the EditText
:
java.lang.IllegalArgumentException: width and height must be > 0
followed by a stack-trace that doesn't contain any of my classes. As you can see in the code below all sizes are set.
What you see below is the current status of the code (I removed some of the code and I hope it still makes sense). I also tried to use what's inside of handler.post()
in the main thread, use the commented stuff instead of the handler.post()
...
What's not below is an attempt to use a RelativeLayout
with the EditText
and the KeyboardView
in one layout-XML. There was a different exception, something like "invalid type 0x12" or something when creating the layout.
It just doesn't work or I just don't know how to do it. Can开发者_运维知识库 anyone please guide me through this? Please let me know if something is missing.
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) {
:
}
}
After hours of "research and trying" stuff, I finally understood my mistake, which seems to be "sjngm"'s one. In order for a virtual keyboard to render, you must
- declare the view either by inflating a layout xml file, or by declaring in row your
KeyboardView
(just as you would do it for an otherView
). - And what was forgotten here: retrieve your KeyboardView with
findViewById()
and call on it:keyboardViewInstance.setKeyboard(new Keyboard(...) );
That's it. You will be able to see your keyboardView on the screen! Of course, you need to either create your own Keyboard class, or to use the existing one with an xml resource file defining your keyboard keys (res/xml/keyboard.xml)
.
I'm currently reinventing my approach as I think that I didn't break the InputMethodService
enough to have it work without itself. In other words I threw away the sample and started from scratch to get the layout working (it's now one layout instead of two) and then added the code from the sample to handle the inputs properly.
After further research I found a really helpful question about an App-specific soft-keyboard. If you run into my situation, look there.
精彩评论