Return false in onEditorAction - android

The TextView's onEditorAction method's documentation says
Return true if you have consumed the action, else false.
Most examples I see online return true. But in this case, the soft keyboard stays opened.
Is it legit to return false to let the system handle the soft keyboard or does that have any side effects?
private TextView.OnEditorActionListener inputListener = new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
switch (actionId) {
case EditorInfo.IME_ACTION_NEXT:
Toast.makeText(MainActivity.this, "Next", Toast.LENGTH_SHORT).show();
break;
case EditorInfo.IME_ACTION_DONE:
Toast.makeText(MainActivity.this, "Done", Toast.LENGTH_SHORT).show();
break;
}
return false;
}
};

That's totally OK.
The documentation refers to the action you want to make, if you succeeded in your action, return true. false otherwise.
So.. the keyboard doesn't matter here. if you have problem with the keyboard just hide it yourself.
// Check if no view has focus:
View view = this.getCurrentFocus();
if (view != null) {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}

Related

Keyboard should show always and should not minimize until i press back

I have a chat feature in my application. everything is working fine. The problem i am facing is that i have an edittext and a button for sending the text. Now when i press the send button the keyboard comes down which i don't want.
Because it is very annoying for the user to open the keyboard after sending every message. Does anyone have any solution for this. it is a very silly issue but it is quite important for me. and is there any change in xml or manifest which we can make which will help solve this problem
Try the below code:
#Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
// User has pressed Back key. So hide the keyboard
InputMethodManager mgr = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
mgr.hideSoftInputFromWindow(this.getWindowToken(), 0);
// TODO: Hide your view as you do it in your activity
} else if (keyCode == KeyEvent.KEYCODE_MENU) {
// Eat the event
return true;
}
return false;
}
I was faced with the same thing in one of my project's. Try doing this to show keyboard
private void showKeyboard(){
InputMethodManager imgr = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imgr.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
yourEditText.requestFocus();
}
This makes the keyboard go down only when back is pressed.
According to this answer.
EditText txtEdit = (EditText) findViewById(R.id.txtEdit);
txtEdit.setOnEditorActionListener(new OnEditorActionListener() {
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
// your additional processing...
return true;
} else {
return false;
}
}
});
Let me know if it solves your problem.
if you return true from your onEditorAction method, action is not going to be handled again. In this case you can return true to not hide keyboard when action is EditorInfo.IME_ACTION_DONE.
Hope it will help !

Contextual ActionBar hides when I click on hardware backbutton and the keyboard is out

I am using the Contextual ActionBar for editing and when I have the keyboard shown and I want to hide it by pressing the hardware back button, it hides the keyboard but it also cancels the contextual actionbar and I really canĀ“t find a way how to keep it on.
Anyone?
You should try to override the Back Key hardware, and handle the expected behaviour with a boolean as follows:
// boolean isVisible to retrieve the state of the SoftKeyboard
private boolean isVisible = false;
// isVisible becomes 'true' if the user clicks on EditText
// then, if the user press the back key hardware, handle it:
#Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
// check isVisible
if(isVisible) {
// hide the keyboard
InputMethodManager mImm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
mImm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
isVisible = false;
} else {
// remove the CAB
mActionMode.finish();
}
}
return false;
}
Another solution might be to call dispatchKeyEvent method which is still called when the CAB is displayed:
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
// check CAB active and isVisible softkeyboard
if(mActionModeIsActive && isVisible) {
InputMethodManager mImm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
mImm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
isVisible = false;
return true;
// Maybe you might do not call the 'else' condition, anyway..
} else {
mActionMode.finish();
return true;
}
}
return super.dispatchKeyEvent(event);
}
This should do the trick, but I have not tested it. Hope this helps.
Sources: How to Override android's back key when softkeyboard is open - Prevent to cancel Action Mode by press back button

onKey and exceptions

I'm building an Android application and I'm facing 2 problems. I'm currently using the onKey method to parse a textbox to fetch the user typed data. This is working fine but if the user choose to let the textbox blank and send the data this will cause my application to crash. I would like to add a try and catch to handle/ignore that exception and send nothing if there is a blank even if the enter key is pressed.
My second problem occur when I press the enter key. This cause to send the data 2 times and it's kinda annoying. I think it's because there is no debounce in my code and the program register a key press and a key release. I don't really know how to filter this and I may need some inputs.
Here is my code :
//Listen to the "Enter" button state changes by user selection of keypad
txtSetKp.setOnKeyListener(new OnKeyListener(){ //This method waits for the "enter" key to be hit
public boolean onKey(View arg0, int arg1, KeyEvent arg2) {
switch(arg1)
{
case KeyEvent.KEYCODE_ENTER:
float newSetKp = Float.parseFloat(txtSetKp.getText().toString());
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); //If "enter" pressed, hide keyboard
if(btSocket != null && btSocket.isConnected()){
mConnectedThread.send("P" + newSetKp);
Log.e(TAG, "P"+newSetKp);
}
imm.hideSoftInputFromWindow(txtSetPoint.getWindowToken(), 0);
return true;
default:
return false;
}
}
});
//Listen to the "Enter" button state changes by user selection of keypad
txtSetKi.setOnKeyListener(new OnKeyListener(){ //This method waits for the "enter" key to be hit
public boolean onKey(View arg0, int arg1, KeyEvent arg2) {
switch(arg1)
{
case KeyEvent.KEYCODE_ENTER:
float newSetKi = Float.parseFloat(txtSetKi.getText().toString());
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); //If "enter" pressed, hide keyboard
mConnectedThread.send("I" + newSetKi);
imm.hideSoftInputFromWindow(txtSetPoint.getWindowToken(), 0);
return true;
default:
return false;
}
}
});
Thanks for all your help!
for first problem first check whether the text is empty.
if(txtSetKi.getText().length() != 0)
// perform task
for the second problem use
if(keyEvent == KeyEvent.ACTION_DOWN)
// perform task
or
if(keyEvent == KeyEvent.ACTION_UP)
// perform task
Try this
txtSetKp.setImeOptions(EditorInfo.IME_ACTION_DONE);
txtSetKp.setOnEditorActionListener(new OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
String text = txtSetKp.getText().toString();
if(isNullOrEmpty(text))
System.out.println("Empty");
else
System.out.println("Correct");
return false;
}
});
}
public boolean isNullOrEmpty(String value) {
return value == null || value.length() == 0;
}

Open keyboard only on second touch on an EditText

I am trying to achieve the following: my layout has a number of EditTexts. When the user touches one of the EditTexts for the first time, the keyboard should not open but the EditText should just gain focus. This is because I am doing a calculation in the EditText when it gains focus and I want to display the result to the user. Then when the user has seen the result he can touch the EditText again which will selectAll and open the keyboard to enter a new number.
This is the code I am using right now:
myEditText.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if(iFocus == R.id.eTmyEditText) {
if(iCount == 3) {
myEditText.selectAll();
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(myEditText, InputMethodManager.SHOW_IMPLICIT);
}
if(iCount > 3) return false;
iCount++;
}
else iCount=0;
myEditText.requestFocus();
return true;
}
});
I am using the iCount variable to distinguish the first touch from the second and the ones which will follow. iFocus is set in the focusChangeListener and holds the last EditText which had focus.
The code is working fine sometimes but not always. From time to time the keyboard is not opening or already on the first touch, sometimes the text is not selected, etc.
Is it possible that the TouchEvent bounces somehow? So that the TouchListener is executed more often than I would expect it to be? I also tried to separate the down event and the up event but this does not help.
Has anyone a good idea how what I am trying to do could be implemented in a better way? Thanks
EDIT: this is my final solution:
myEditText.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
myEditText.requestFocus();
if(iCount == 1){
myEditText.postDelayed(new Runnable() {
public void run() {
InputMethodManager manager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
manager.showSoftInput(myEditText, 0);
myEditText.selectAll();
}
}, 200);
}
iCount++;
break;
default:
break;
}
if(iCount >= 2) return false;
else return true;
}
});
Try this, its working for me when I touch the EditText two Times.
mEditText.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
iCount++;
if(iCount == 2){
mEditText.requestFocus();
InputMethodManager manager = (InputMethodManager)
getSystemService(Context.INPUT_METHOD_SERVICE);
manager.showSoftInput(mEditText, 0);
iCount = 0;
}
break;
default:
break;
}
return true;
}
});
Try to replace
myEditText.setOnTouchListener(...);
with
myEditText.setOnClickListener(...);
Have a TextView that has the same background and size as the EditText, and switch between them on first tap, and switch them back again when the EditText loses focus.
Or store the current getKeyListener(), setKeyListener(null) and then restore after first click.
Or subclass EditText and override getDefaultEditable() to return false unless it already has focus.

android set hidden the keyboard on press enter (in a EditText)

When my user press Enter on the virtual android "user validate entry!" keyboard my keyboard stay visible! (Why?)
Here my Java code...
private void initTextField() {
entryUser = (EditText) findViewById(R.id.studentEntrySalary);
entryUser.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_ENTER:
userValidateEntry();
return true;
}
}
return true;
}
});
}
private void userValidateEntry() {
System.out.println("user validate entry!");
}
... here my View
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content">
<EditText android:id="#+id/studentEntrySalary" android:text="Foo" android:layout_width="wrap_content" android:layout_height="wrap_content" />
</LinearLayout>
Maybe something wrong on my virtual device?
This should do it:
yourEditTextHere.setOnEditorActionListener(new OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId,
KeyEvent event) {
if (event != null&& (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) {
InputMethodManager in = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
// NOTE: In the author's example, he uses an identifier
// called searchBar. If setting this code on your EditText
// then use v.getWindowToken() as a reference to your
// EditText is passed into this callback as a TextView
in.hideSoftInputFromWindow(searchBar
.getApplicationWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
userValidateEntry();
// Must return true here to consume event
return true;
}
return false;
}
});
Keep the singleLine="true" and add imeOptions="actionDone" to the EditText.
Then in the OnEditorActionListener check if actionId == EditorInfo.IME_ACTION_DONE, like so (but change it to your implementation):
if (actionId == EditorInfo.IME_ACTION_DONE) {
if ((username.getText().toString().length() > 0)
&& (password.getText().toString().length() > 0)) {
// Perform action on key press
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(username.getWindowToken(),
0);
doLogin();
}
}
If you make the text box a single line (I believe the propery is called SingleLine in the layout xml files) it will exit out of the keyboard on enter.
Here you go: http://developer.android.com/reference/android/R.styleable.html#TextView_singleLine
I am create a custom component who extends AutoCompleteTextView, like in the example below:
public class PortugueseCompleteTextView extends AutoCompleteTextView {
...
#Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (event != null && (event.getKeyCode() == KeyEvent.KEYCODE_BACK)) {
InputMethodManager inputManager =
(InputMethodManager) getContext().
getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(
this.getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
}
return super.onKeyPreIme(keyCode, event);
}
I am using this code in the AlertDialog.Builder, but is possible to be using to Activity.
just add this line in your edit text.
android:imeOptions="actionDone"'
you can specify the next edit text id to move to that edit text on click of the keyboard done button.

Categories

Resources