Reputation: 165
I'm currently working on developing a custom keyboard app that will be optimized for a device using a DPad as its primary input device.
My problem is that When the cursor is in the EditText field and you press down (e.g. KEYCODE_DPAD_DOWN), the keyboard view is not receiving focus and KeyEvents. Either nothing happens, or the element beneath the EditText in question receives focus.
Below is the relevant code.
Any help would be much appreciated. I've tried dissecting the SoftKeyboard example aswell as KeyboardView.java for hints without success.
Thanks, Bryan
MyKeyboard.java
public class MyKeyboard extends InputMethodService {
private static final String TAG = "MyKeyboard";
private MyKeyboardView mInputView = null;
@Override public void onCreate() {
super.onCreate();
}
@Override public View onCreateInputView() {
mInputView = (MyKeyboardView) getLayoutInflater().inflate(R.layout.input, null);
// attempts to make this focusable
mInputView.setClickable(true);
mInputView.setFocusableInTouchMode(true);
mInputView.setFocusable(true);
mInputView.setEnabled(true);
return mInputView;
}
@Override public View onCreateCandidatesView() {
super.onCreateCandidatesView();
return null;
}
@Override public void onStartInputView(EditorInfo info, boolean restarting) {
super.onStartCandidatesView(info, restarting);
}
@Override public void onFinishInput() {
super.onFinishInput();
}
@Override public void onDestroy() {
super.onDestroy();
}
}
MyKeyboardView.java
public class MyKeyboardView extends TableLayout implements View.OnClickListener, View.OnFocusChangeListener {
private static final String TAG = "MyKeyboardView";
private ArrayList<Character> charList = new ArrayList<Character>();
public MyKeyboardView(Context context) {
super(context);
populateKeyboard();
this.setOnFocusChangeListener(this);
this.setOnClickListener(this);
}
public MyKeyboardView(Context context, AttributeSet attrs) {
super(context, attrs);
populateKeyboard();
this.setOnFocusChangeListener(this);
this.setOnClickListener(this);
}
@Override
public void onClick(View arg0) {
Log.d(TAG, "onClick");
}
private void populateKeyboard() {
charList.add(new Character(','));
charList.add(new Character('.'));
charList.add(new Character('?'));
charList.add(new Character('<'));
charList.add(new Character('>'));
charList.add(new Character((char) 0x2798)); // arrow
charList.add(new Character((char) 0x2798)); // arrow
charList.add(new Character((char) 0x2798)); // arrow
charList.add(new Character((char) 0x005F)); // underscore
for(char c = '@'; c < 'Z'; c++) {
charList.add(new Character(c));
Log.d(TAG, "char: " + c);
}
TableRow tr = null;
for(int i=0; i<charList.size(); i++) {
if(i % 7 == 0) {
if(tr != null)
this.addView(tr);
tr = new TableRow(this.getContext());
tr.setGravity(Gravity.CENTER_HORIZONTAL);
}
TextView tv = new TextView(this.getContext());
tv.setPadding(21, 2, 21, 2);
tv.setText(charList.get(i).toString());
tv.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 22);
tv.setTextColor(Color.WHITE);
tv.setGravity(Gravity.CENTER);
tv.setFocusable(true);
tv.setEnabled(true);
tr.addView(tv);
}
if(tr.getChildCount() > 0)
this.addView(tr);
}
@Override
public void onFocusChange(View v, boolean hasFocus) {
Log.d(TAG, "mInputView onFocusChange " + (hasFocus ? "true" : "false"));
}
}
input.xml
<?xml version="1.0" encoding="utf-8"?>
<com.weirdtuesday.mykeyboard.MyKeyboardView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#FF000000"
android:focusable="true" />
Upvotes: 7
Views: 2645
Reputation: 2854
Key events must be processed manually in the onKey method. To move the cursor, I use this:
if (primaryCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
int position = connection.getTextBeforeCursor(Integer.MAX_VALUE, 0)
.length();
final CharSequence selected = connection.getSelectedText(0);
if (selected != null)
connection.commitText(
mComposing.substring(0,
mComposing.length() - selected.length()), 1);
else
connection.commitText(mComposing, 1);
connection.setSelection(position + 1, position + 1);
}
Upvotes: 2