How to capture soft keyboard input in a View? –

Development issue/problem:

I have a view subclass that appears on the keyboard when I touch it in the onTouchEvent. He shows it by asking for focus, getting the InputMethodManager and then calling showSoftInput.

Now I have to figure out how to capture the letters on the soft keyboard that are pressed. At this moment I only get an answer when I press Next/Complete on the programmable keyboard.

This is my class:

BigGrid public class extends the view {

private static finite string TAG = BigGrid ;

public BigGrid(context) {
super(context);
setFocusableInTouchMode(true); // expand keyboard to
// touchdown

setOnKeyListener(new OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
Log.d(TAG, onKeyListener);
if (event.getAction() == KeyEvent.ACTION_DOWN) {
// execution of key action
Log.d(TAG, ACTION_DOWN);
return true;
}
return false;
}
}) ;
}

@Check
logical general onTouchEvent(event MotionEvent) {
super.onTouchEvent(event);
Log.d(tag, onTOUCH);
if (event.getAction() == MotionEvent.ACTION_UP) {

// show the keyboard to enter text
InputMethodManager imm = (InputMethodManager) getContext()
.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(this, InputMethodManager.SHOW_FORCED);
}
return true;
}

Check
Public Input Terminal forCreateInputConnection(EditorInfo outAttrs) {
Log.d(TAG, onCreateInputConnection) ;

BaseInputConnection fic = new BaseInputConnection (this, true);
outAttrs.actionLabel = null;
outAttrs.inputType = InputType.TYPE_CLASS_TEXT;
outAttrs.imeOptions = EditorInfo.IME_ACTION_NEXT;
return fic;
}.

@Check
public boolean function onCheckIsTextEditor() {
Log.d(TAG, onCheckIsTextEditor);
return true;
}

@Override
public blank onDraw(Canvas) {
super.onDraw(Canvas canvas) ;

canvas.drawColor(R.color.grid_bg);
// .
// .
// more character code .
// .
}
}

The keyboard is displayed, but my onKeyListener is only activated when I press the Next key on the keyboard. I need the symbol to display it in my onDraw() method.

How can I solve this problem?

Solution 1:

This is because it is possible to manage the most important events yourself without the need for text display.

To do this, you can change your source code as follows:

1) Replace the following line in onCreateInputConnection() :

outAttrs.inputType = InputType.TYPE_CLASS_TEXT ;

so that..:

outAttrs.inputType = InputType.TYPE_NULL ;

In the documentation for InputType.TYPE_NULL : This should be interpreted as meaning that the target input connection is not rich, that it cannot process and display things such as candidate text or current text, so the input method should be performed to a limited extent to generate important events.

2) Replace the next line in the same way:

BaseInputConnection fic = new BaseInputConnection (this, where) ;

so that..:

BaseInputConnection fic = new BaseInputConnection (this is wrong) ;

The second fake argument sets BaseInputConnection to the dummy mode, which is also needed to send raw key events to your view. There are several remarks in the BaseInputConnection code, such as. B. the following: Only in the case of the dummy mode, an important event on the new text is sent and the current editable buffer is deleted.

I have used this approach to have the programmable keyboard send rough events derived from LinearLayout (i.e. an opinion that is not derived from TextView), and I can confirm that it works.

Of course, if you don’t need to set the IME_ACTION_DONE imeOptions to display the Done button on the keyboard, you can remove the onCreateInputConnection() and onCheckIsTextEditor() options completely. Raw events are then sent to your default view because no input connection has been defined that can perform more complex operations.

But unfortunately there doesn’t seem to be an easy way to set up EditorInfo attributes without overwriting these methods and providing a BaseInputConnection object, and once you have done this, you will have to stop processing by this object as described above if you want to receive unprocessed key events again.

A WARNING: In some recent versions of the standard LatinIME keyboard that comes with Android (Google Keyboard), two bugs have been introduced that can affect the handling of keyboard events (as described above) when using this keyboard. I have developed a number of workarounds on the side of the application, with a sample code that seems to work around these things. To see these workarounds, see the following answer:

Android – cannot capture backspace/removal keys on the keyboard.

Solution 2:

It turns out I actually needed a TextView subclass and the use of addTextChangedListener() to add my own implementation of TextWatcher that listens to softkey events. I couldn’t find a way to do it with a simple overview.

One more thing, for those who are trying this technique; TextView cannot change the default text, so if you want to make your implementation editable (instead of an EditText subclass, which I didn’t want to do), you should also create a custom InputConnection, something like the one shown below:

/**
* MyInputConnection
* BaseInputConnection configured for edition
*/
class MyInputConnection expands BaseInputConnection {
private SpannableStringBuilder _editable;
TextView ;

public MyInputConnection(View targetView, boolean fullEditor) {
super(targetView, fullEditor);
_textView = (TextView) targetView;
}

public Editable getEditable() {
if (_editable == null) {
_editable = (SpannableStringBuilder) Editable.Factory.getInstance()
.newEditable(Placeholder);
}
returns _editable;
}

public boolean commitText(CharSequence text, int newCursorPosition) {
_editable.append(text);
_textView.setText(text);
return true;
}
}.

Then overwrite OnCheckisTextEditor and OnCreateInputConnection with something like the following:

@Check
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
outAttrs.actionLabel = null;
outAttrs.label = Testtext;
outAttrs.inputType = InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;
outAttrs.imeOptions = EditorInfo.IME_ACTION_DONE ;

return the new MyInputConnection (this, true);
}

@CheckIsTextEditor() {to which to return;}

Then you should have a view that allows you to listen to the softkey, and you can do whatever you want with the keyboard values.

Solution 3:

According to the documentation, the view (editor) receives commands from the keyboard (IME) via InputConnection and sends commands to the keyboard via InputMethodManager.

I’ll show you all the code below, but here are the steps.

1. Make the keyboard visible

Since the view sends a command to the keyboard, the InputMethodManager must be used. For example, let’s say that clicking on the display will display (or hide, if it’s already displayed) the keyboard.

@General Boolean control
onTochevent(event MotionEvent) {
if (event.getAction() == MotionEvent.ACTION_UP) {
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, InputMethodManager.HIDE_IMPLICIT_ONLY);
}
return true;
}.

The image should also have been focused (true) in touch mode earlier.

2. Keyboard input reception

In order to receive keyboard input, the OnCreateInputConnection() must overwrite. This returns the InputConnection that the keyboard uses to communicate with the display.

@General
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
outAttrs.inputType = InputType.TYPE_CLASS_TEXT;
offers new MyInputConnection(this, true);
}

The OutAttrs indicate which keyboard is requested by the view. It’s just a text keyboard. If NUMBER_CLASS_TYPE is selected, the number bar is displayed (if available). There are many more possibilities. Look, look, look, look, look, look. EditorInfo.

You must return InputConnection, which is normally its own subclass of BaseInputConnection. In this subclass you give a reference to your editable string that is updated from the keyboard. Since the SpannableStringBuilder implements the modifiable interface, we will use it in our main example.

the MyInputConnection public class extends the BaseInputConnection {

SpannableStringBuilder privately editable ;

MyInputConnection(View targetView, boolean fullEditor) {
super(targetView, fullEditor);
MyCustomView customView = (MyCustomView) targetView;
mEditable = customView.mText;
}

@Override
public Editable getEditable() {
return mEditable;
}
}

The only thing we have done here is an input link with a reference to a text variable in our custom view. BaseInputConnection takes care of the processing of this mText. Maybe that’s all you need to do. However, you can look at the source code and see what methods the standard implementation says, especially the standard implementation does nothing. These are other methods you may want to replace, depending on the scope of your view of the editorial staff. You should also check all method names in the documentation. Some contain notes about the authors/editors. Pay special attention to this.

For some reason, some keyboards do not control certain inputs via InputConnection (e.g. Delete, Enter and some number keys). For this last one I added OnKeyListener. When testing this configuration on five different software keyboards, everything seemed to work. More answers to this topic can be found here:

Full project code

Here’s my full example for reference.

MyCustomView.java

The MyCustomView public class expands the view {

SpannableStringBuilder mText ;

public MyCustomView(context) {
this(context, zero, 0);
}.

public MyCustomView(Context, AttributeSet attrs) {
this(context, attrs, 0);
}

public MyCustomView(Context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}

private void init() {
setFocusableInTouchMode(true) ;
mText = new SpannableStringBuilder() ;

// {public boolean onKey(View v, int keyCode, KeyEvent event) {as (event.getAction() == KeyEvent.ACTION_DOWN) {

if (event.getUnicodeChar() == 0) { // check the characters

if (keyCode == KeyEvent.KEYCODE_DEL) {mText.delete(mText.length() – 1, mText.length());Log.i(TAG, text: + mText + (keycode));returns true;}}// TODO here handles any other control key} differently { // text charactersmText.append((char)event.getUnicodeChar());Log.i(TAG, text: + mText + (keycode));return true;}}}return false;});}.

// switches the keyboard layout when the view
@General Boolean Window
onTouchEvent(event MotionEvent) {
if (event.getAction() == MotionEvent.ACTION_UP) {
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, InputMethodManager.HIDE_IMPLICIT_ONLY);
}
return true;
}

@General
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
outAttrs.inputType = InputType.TYPE_CLASS_TEXT;
// outAttrs.inputType = InputType.TYPE_CLASS_NUMBER; // alternatively (display of a block of numbers, no text)
returns a new MyInputConnection(this, true);
}
}

MyInputConnection.java

the MyInputConnection public class extends the BaseInputConnection {

SpannableStringBuilder privately editable ;

MyInputConnection(View targetView, boolean fullEditor) {
super(targetView, fullEditor);
MyCustomView customView = (MyCustomView) targetView;
mEditable = customView.mText;
}

@Override
public Editable getEditable() {
return mEditable;
}

// This has only been added to indicate that the text is fixed.
@Override
public boolean commitText(CharSequence text, in newCursorPosition) {
boolean returnValue = super.commitText(text, newCursorPosition);
Log.i(TAG, text: + mEditable);
returnValue;
}
}

Active_main.xml

The code of MainActivity.java is nothing special.

Leave a comment if this doesn’t work. I use this basic solution for custom EditText in the library I build, and if there are extreme cases where it doesn’t work, I want to know. If you want to see this project, you can find the custom view here. This is InputConnection.

Partner

Solution 4:

As I understand it, your onKeyListener only receives important events from the hardware.

You can access all important input events when you bypass the logical event View.onKeyPreIme (int keyCode, KeyEvent).

Thus, you can choose to treat the key event action [ DOWN | MULTIPLE | UP ] and return where, or to allow normal key handling (return super.onKeyPreIme()).

Good luck!

Related Tags:

android key event listener example,android send key event programmatically,android keypress event javascript,android keyboard enter key action,onkeydown not working android,how to handle keyboard back button in android,android soft keyboard,android soft keyboard key listener,android show keyboard programmatically,android input method service example,android keyboard navigation,android force keyboard show,keydown in fragment android,dispatchkeyevent in fragment android,keycode android,usewindowsoftinputmodeadjust,xamarin forms windowsoftinputmode,xamarin forms keyboard overlap,xamarin forms is keyboard visible,adjust keyboard in xamarin forms,keep keyboard open xamarin forms,how to adjust layout when soft-keyboard appear in android,android soft keyboard listener,window's soft input mode,android keyboard covers text input,how to get keycode in android

Leave a Reply

Your email address will not be published.