Android - How to hide softkeyboard if EditText is empty on key press? - java

I'm working on a project to make calculations. So, I have my EditText box working, and I want to hide the softkeyboard if the user clicks the DONE (or any other kind of button, GO, NEXT, etc.) and the EditText box is empty
Like so:
EditText is empty -> user clicks button -> softkeyboard hides
I have this piece of code that I manage to write using tutorials and guides over the internet
I do know it is to manage the listener of the button in the softkeyboard
TextView.OnEditorActionListener mEditor = new TextView.OnEditorActionListener()
{
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event)
{
if (actionId == EditorInfo.IME_ACTION_DONE)
{
//Calculations method
}
return false;
}
};
So, my question is: How can I manage the listener when the EditText is empty and not get errors?

you can use, for example:
TextView.OnEditorActionListener mEditor = new TextView.OnEditorActionListener()
{
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event)
{
if (actionId == EditorInfo.IME_ACTION_DONE)
{
if (!TextUtils.isEmpty(v.getText().toString())){
// you calculations method
} else {
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(
Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getApplicationWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
}
}
return false;
}
};

Related

How can I keep the soft keyboard up when switching to the next EditText in a recycler view?

The problem I am facing is when the user clicks the next button on the keyboard, the program should focus onto the next EditText on the screen and keep the keyboard open until there are no more enabled EditTexts on the screen. When there are no more enabled EditTexts, the keyboard should disappear.
Another issue is when there is an EditText that isn't currently visible on screen then it will not gain focus until the user selects it.
I have tried using the Input Method Manager to show the keyboard when the EditText has focus and hide when there is none. If there are no more enabled EditTexts enabled, the keyboard is still present.
final InputMethodManager imm = (InputMethodManager)
context.getSystemService(Context.INPUT_METHOD_SERVICE);
if (variable.getType().equals("Value")) {
if (variable.getFormat().equals("Number") || variable.getFormat().equals("2Number")) {
viewHolder.inputValue.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean hasFocus) {
if(hasFocus){
imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
} else if(hasFocus && !viewHolder.inputValue.isEnabled()){
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
});
} else if (variable.getFormat().equals("Text")) {
viewHolder.messageText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean hasFocus) {
if(hasFocus){
imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
} else if(hasFocus && !viewHolder.inputValue.isEnabled()){
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
});
}
} else if (variable.getType().equals("Message")) {
viewHolder.messageText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean hasFocus) {
if(hasFocus){
imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
} else if(hasFocus && !viewHolder.inputValue.isEnabled()){
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
});
} else {
//imm.hideSoftInputFromWindow(viewHolder.itemView.getWindowToken(), 0);
}
The EditTexts are stored within cardviews inside a recyclerview. Each card has a variable type. Only "Value" and "Message" variable types should receive focus when clicking the next button on the keyboard.
I expect the user to be able to scroll through enabled EditTexts within the RecyclerView by clicking the next button on the keyboard. If an EditText is not within view on screen the screen should scroll down to it to gain focus. Also, if the EditText is disabled it should never gain focus.
Override the onEditorAction method and return true for each editText you want to keep the keyboard open.
edittext.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
//optional: you can run some logic here.
}
//return true to not hide the keyboard
return true;
}
});

Make EditText pass focus back to parent layout when finished editing.

I have a linear layout in a fragment with a bunch of checkboxes and various edittext widgets inside it. Basically like a quiz. A bunch of multiple choice(checkboxes) and a dozen short answer(edittexts) questions.
What I would like is for users to be able to click an edittext, type in an answer, then press DONE or click anywhere else on the layout and have the widget lose focus and the keyboard hide. Currently I am overriding the setOnEditorActionListener and setOnFocusChangeListener methods of each edittext to give focus back to a main layout, and hide the keyboard respectively. Here is the code for an edittext instance called "input_7d":
final EditText input_7d = (EditText) thisview.findViewById(R.id.txtinput_7d);
final LinearLayout parentLayout = (LinearLayout) thisview.findViewById(R.id.main_layout);
input_7d.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if(actionId == EditorInfo.IME_ACTION_DONE) {
parentLayout.requestFocus();
}
return false;
}
});
input_7d.setOnFocusChangeListener(new TextView.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if(!hasFocus){
InputMethodManager imm = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(parentLayout.getWindowToken(),InputMethodManager.HIDE_NOT_ALWAYS);
}
}
});
This is annoying to do for every edittext I add, and it means editing lots of code if I remove them or add more in the future. What I would like to do is have a custom edittext class that can return focus to it's parent view/layout and hide the keyboard, then use that instead of the built in edittext. I'm very new to this and I haven't been able to find a way for a custom edittext to pass focus back to it's parent layout. Is there a better way to get a bunch of edittexts to all have this behavior and not have it all "hardcoded" into my fragment class?
So I could not find a way to have a edittext pass focus back to it's parent layout from inside the view itself. So instead I have opted to just disable focusable property of it when it
1) It loses focus (user clicked outside the view on something focusable, ie. The parent layout)
2) Finishes it's edit(user presses Done action on soft keyboard)
Surprisingly neither of these actions by default remove focus and the cursor from a default editText. At least not inside my scroll views.
So I added these lines to a custom view(myEditText) that extends the editText view:
this.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if(actionId == EditorInfo.IME_ACTION_DONE) {
myEditText.setFocusable(false);
myEditText.setFocusableInTouchMode(false);
}
return false;
}
});
this.setOnFocusChangeListener(new TextView.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if(!hasFocus){
myEditText.setFocusable(false);
myEditText.setFocusableInTouchMode(false);
hideKeyboardFrom(context, v);
}
}
});
this.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
myEditText.setFocusableInTouchMode(true);
myEditText.setFocusable(true);
return false;
}
});
I find it really annoying that to get simple functionality like not having the cursor blinking at me always or having the view not take focus when changing fragments and such you have to do such a weird workaround. Making a view unfocusable unless it's focused in which case it is focusable but only until it isn't focused again just seems dumb. Still wondering if there is a better way to do this for a large number of edits in one layout.
you can set a touch listener for the root layout and then remove the focus whenever not needed for the view
findViewById(R.id.rootView).setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
v.requestFocusFromTouch() //check for y
return false;
}
});

How to handle android keyboard actions

I am new to Android. I am trying to make a text box and on pressing done key, it should take the value to the java code. For this I am using setOnEditorActionListener.. I searched on how to do this and got many answers on how to implement it. Example:
EditText editText = (EditText) findViewById(R.id.search);
editText.setOnEditorActionListener(new OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
boolean handled = false;
if (actionId == EditorInfo.IME_ACTION_SEND) {
sendMessage();
handled = true;
}
return handled;
}
});
I need to ask where should I write this thing? In which method? I tried doing it in onCreate but it threw some error. I somehow made it work using this code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.unlock);
Log.i(TAG, "onCreate");
editText= (EditText) findViewById(R.id.editText);
editText.setOnEditorActionListener(this);
}
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
boolean handled = false;
if (actionId == EditorInfo.IME_ACTION_SEND) {
Log.i(TAG, "button pressed");
Toast.makeText(this, "Hey you just clicked the DONE button", Toast.LENGTH_SHORT).show();
handled = true;
}
return handled;
}
Here I used this keyword, and I don't understand why have I used it.
Question 1. Please help me understand, why have we used this keyword..
Question 2. Why wasn't it working in the below code?
public void checkInput() {
Log.i(TAG, "Enter checkInput method");
final EditText editText= (EditText) findViewById(R.id.editText);
editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
Log.i(TAG, "Enter onEditorAction");
boolean handled = false;
if (actionId == EditorInfo.IME_ACTION_SEND) {
Log.i(TAG, "button pressed")
handled = true;
}
return handled;
}
});
}
I called this checkInput method from onCreate.
To answer Question 1:
Here I used this keyword, and I don't understand why have I used it. Question 1. Please help me understand, why have we used this keyword..
You're telling Java to look into the Activity class for implementations of methods required by the TextView.OnEditorActionListener interface. So for all interactions with your soft keyboard, Java would look into your class for the method: onEditorAction
In order for the above to work, your activity needs to defined like:
public class MyActivity implements TextView.OnEditorActionListener {}
For question 2:
Question 2. Why wasn't it working in the below code?
To check for the "Done" action, your if statement should be:
if (actionId == EditorInfo.IME_ACTION_DONE) { ... }
Hope that helps.

How to detect when "Go" is pressed on Android Keyboard

I'm trying to detect when "Go" is pressed on the android Keyboard (the last key on the bottom right).
My code works in the emulator and on my Nexus 5, but doesn't on some other Android devices.
What am I doing wrong?
editTextMain.setImeActionLabel("Go", KeyEvent.KEYCODE_ENTER);
editTextMain.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) {
if(i==KeyEvent.KEYCODE_ENTER)
{
Intent intent = new Intent(thisActivity, ActivityRisultati.class);
startActivity(intent);
return true;
}
}
}
Try this
editText = (EditText) findViewById(R.id.edit_text);
editText.setOnEditorActionListener(new OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
// do your stuff here
}
return false;
}
});
I have some code in my app which detects when any key which sends the KEYCODE_ENTER value is pressed. It detects both the Enter and Done keys on a Motorola Droid 3 slide-out keyboard. Here's my code:
private OnKeyListener enterKeyListener = new OnKeyListener()
{
public boolean onKey(View v, int k, KeyEvent e)
{
/*
* "Enter" or "Done" key was pressed
*/
if( (e.getKeyCode() == KeyEvent.KEYCODE_ENTER) && (e.getAction() == KeyEvent.ACTION_UP) )
{
//
// Do some stuff ...
//
return true;
}
return false;
}
};
Note the additional check for KeyEvent.ACTION_UP. You might need that on some devices in order to prevent the listener from firing as soon as the button is pressed, and repeatedly if the button is held down. In my case, I only wanted it to take an action if the key had been pressed and then released.
Hope this helps.

On enter,jump to next EditText issue

I have 3 EditTexts in a row but on 3 different layouts. I set them up so when i click enter,it will jump to the next EditText from that row,on the next layout.The problem is that when i click enter from the first EditText on the row,it goes to the third.From the third it goes to the second and from the second to the first.It's like i press enter on the first EditText,it goes to the second and then to the third on the same enter.
How can i stop it from jumping for example from the first EditText to the second and then the third on the same press of the enter key?
Here's some of my code :
et.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View v1, int keyCode, KeyEvent KEYCODE_ENTER) {
l2.getChildAt(localizarer).requestFocus();
return true;
}
});
et2.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View v2, int keyCode, KeyEvent KEYCODE_ENTER) {
l3.getChildAt(localizarer).requestFocus();
return true;
}
});
et3.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View v3, int keyCode, KeyEvent KEYCODE_ENTER) {
l1.getChildAt(localizarer).requestFocus();
return true;
}
});
It's like i need some kind of break function,lol.
How can i fix this ?
Thanks and have a nice day/night !
Fixed by doing this :
et.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
// If the event is a key-down event on the "enter" button
if ((event.getAction() == KeyEvent.ACTION_DOWN) &&
(keyCode == KeyEvent.KEYCODE_ENTER))
{
// Perform action on key press
l2.getChildAt(localizarer).requestFocus();
return true;
}
return false;
}
});
But now an older issue is back,it jumps to my second row of edittexts instead of going to the first child in the layout it goes to the second..
Are your edit texts defined in your xml do you have them in the corrent order there?
if that doesn't work you can use
android:nextFocusDown
to set the order
Why don't you use:
et1.requestFocus();
Instead of
l1.getChildAt(localizarer).requestFocus();

Categories

Resources