I have an activity where a text view gains focus of a keyboard.
I set an ontouchlistener to the parent view; if the click is outside the range of the textview, I am hiding my textview by using ;
InputMethodManager imm = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(textView.getWindowToken(), 0);
My only problem is, if the keyboard is not showing and the parent is clicked on, it keeps firing up those two lines, which ultimately causes useless transactions (I like to save as much processing as possible ..)
I have been trying to use some textview methods like hasfocus or isfocused etc but I can't quite seem to find one that only fires off the text view makes a keyboard show ...
Does anyone know if this is even possible?
THe if statement below is the place I would like to put the method ..
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (textView.*SOME METHOD HERE*?) {
Log.e(TAG, "LOSING FOCUS");
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(textView.getWindowToken(), 0);
}
}
return true;
}
Thanks
Check the configuration. The keyboardHidden value will hold whether any keyboard is out. This will work unless there's a face keyboard (think Blackberry style). If those are important you'll need some more complicated logic including the keyboard field and hardKeyboardHidden fields.
Related
I was wondering, in a Dialog with multiple EditTexts, is there any way to hide the soft keyboard if the user clicks outside any one of them? This dialog has a LOT of EditTexts, and I would like an easy way for the user to hide the soft keyboard.
Since the EditTexts are in the form of a table, I prefer not to use imeOptions="actionDone" for every single EditText, since there are times when the user needs to enter data in an entire column. However, if the user only needs to enter partial data, I would like it where the user can click outside of any EditText and hide the soft keyboard.
I have looked up several solutions here, but none of them seem to work for my scenario. They only seem to work in an activity.
have you tried setting OnTouchListener for ViewGroup parent of all these EditTexts? and when MotionEvent is not consumed by any of them (method returns true/false) then run your method hideKeyboard();? (some examples HERE)
also you wrote
and I would like an easy way for the user to hide the soft keyboard.
isn't Back physical/on-screen button intended to do that? Always accessible in same place on the front of device, the easiest way... (for usual devices, maybe you have some custom...) But I admit that touching outside any EditText closing keyboard is UX-friendly
Okay, it looks like setting the root and child container views to clickable, focusable, and focusableInTouchMode to true did the trick, along with the following code:
public void hideKeyboard(View view) {
InputMethodManager inputMethodManager = (InputMethodManager)getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
public void setupDialog(View view) {
// Set up touch listener for non-text box views to hide keyboard.
if (!(view instanceof EditText)) {
view.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View view, MotionEvent event) {
hideKeyboard(view);
return false;
}
});
}
//If a layout container, iterate over children and seed recursion.
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
View innerView = ((ViewGroup) view).getChildAt(i);
setupDialog(innerView);
}
}
}
Where you pass in the id of the root view of the dialog.
No user clicks outside of a EditText to escape from it. You should better use "actionGo" or "actionDone" for your input fields.
But if you really-really need it, I recommend using onFocusChangeListener.
Use this code to hide keyboard:
InputMethodManager imm = (InputMethodManager) getSystemService(
INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
Then check you have this for your EditText:
android:clickable="true"
android:focusableInTouchMode="true"
I have an EditText where I want to handle the inputs myself, so I don't want the soft keyboard to show up when I click it (or when selection changes, focus changed, long clicked, etc). However, I still want to be able select the text, change cursor position, copy/past, etc.
I have tried putting android:windowSoftInputMode="stateAlwaysHidden" in the manifest, but that doesn't seems to do much. I also tried adding the following
edittext.setOnTouchListener(new OnTouchListener() {
#Override public boolean onTouch(View v, MotionEvent event) {
EditText edittext = (EditText) v;
int inType = edittext.getInputType(); // Backup the input type
edittext.setInputType(InputType.TYPE_NULL); // Disable standard keyboard
edittext.onTouchEvent(event); // Call native handler
edittext.setInputType(inType); // Restore input type
return true; // Consume touch event
}
});
which disables the keyboard, but also prevent the cursor from working.
Currently I'm basically trying to add listeners for all the situations where the keyboard might pop up to toggle it off, but this is very clunky and I can't catch all the cases. Is there a better way to disable the soft keyboard for a particular EditText or fragment?
Obviously the best solution would be if Google gave an inputType that works like this.
The following tends to work. It will sometimes flicker as the keyboard is loaded and then is instantly murdered. But, it just listens for when you click on the textview and then when that happens it murders the keyboard.
It can't account for things like if the textfield gets focus some other way, but for my purposes (I have a textfield for a barcode reader that gets a barcode read into it by a barcode reader (hardware keyboard)), so a softkeyboard makes no sense.
editView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
//imm.hideSoftInputFromWindow(v.getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY);
}
}
});
I also added the other line you might want in there and commented it out. Namely if you want to hide the Android launched soft keyboard or if a user loads the keyboard by holding menu if that might close too.
Try this code.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Disable IME for this application
getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
setContentView(R.layout.activity_layout);
I'm currently developing a calculator app where I have made a custom keypad and would like to hide the virtual keyboard. I have found solutions where I can hide it, but the cursor also gets hidden. The functionality I want is the same as the com.android.calculator2 app. I have looked at the source code of that but I still can't get it to work.
I think you are getting it wrong. There is a much easier solution(and a more obvious one).
Make the EditText uneditable.
Bind to the EditText in your code (findViewById)
In your buttons, get the text and add to the current string and then display it.
Eg.
say you pressed the '1' button.
in your one.setOnclickListener(), do this:
String S=EditText.getText()+"1";
EditText.setText(s);
Edit:
If you just want to hide the keyboard while keeping the cursor, try this code:
EditText editText = (EditText)findViewById(R.id.edit_text);
editText.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
v.onTouchEvent(event);
InputMethodManager imm = (InputMethodManager)v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
return true;
}
});
I'm trying to write text in Canvas. As I need to show the soft keyboard to write text, I added an EditText to my Activity with 0 width. I also implemented a TextWatcher to get the text entered into the EditText. With this trick, I can show the soft keyboard whenever I like with this code :
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(myEditText, InputMethodManager.SHOW_IMPLICIT);
Like this I'm able to know what the user is writing and to write the text inside my Canvas.
Now... this becomes tricky when the user would like to stop writing (or let say, anchor the text in the canvas definitely). What I thought is that he could press 'Enter'. So I tried to implement some way to catch the key events. Without any success so far.
Here is my actual code. This method is called when I would like to start writing. 'edit' is an EditText.
public void handleUp(final Paint myPaint) {
edit.setFocusable(true);
edit.setFocusableInTouchMode(true);
edit.requestFocus();
edit.addTextChangedListener(new Watcher());
edit.setImeOptions(EditorInfo.IME_ACTION_GO);
edit.setOnEditorActionListener(new OnEditorActionListener() {
public boolean onEditorAction(TextView arg0, int arg1, KeyEvent arg2) {
Log.d("MyApp", "key pressed");
Paint localPaint = new Paint();
mCanvas.drawText(edit.getText().toString(), mX, mY, localPaint);
return false;
}
});
edit.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
Log.d("MyApp", "key pressed");
if (keyCode == KeyEvent.ACTION_DOWN) {
Paint localPaint = new Paint();
mCanvas.drawText(edit.getText().toString(), mX, mY, localPaint);
return true;
}
return false;
}
});
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(edit, InputMethodManager.SHOW_IMPLICIT);
}
When I debug my app I never reach check points that I have put on my Log() and can't see any message in my Logs neither. I have seen many posts on StackOverFlow where this kind of implementation is used by I can't figure out why it fails here.
Thank you
Taken from the documentation:
public void setOnKeyListener (View.OnKeyListener l)
Added in API level 1
Register a callback to be invoked when a hardware key is pressed in this view. Key presses in software input methods will generally not trigger the methods of this listener.
So you should look for another listener.
My best guess would be to use this:
public void setOnEditorActionListener (TextView.OnEditorActionListener l)
Added in API level 3
Set a special listener to be called when an action is performed on the text view. This will be called when the enter key is pressed, or when an action supplied to the IME is selected by the user. Setting this means that the normal hard key event will not insert a newline into the text view, even if it is multi-line; holding down the ALT modifier will, however, allow the user to insert a newline character.
But none of the methods I could see in the documentation mentioned anything about soft key input.
You override the dispatchKeyEvent to get the Enter key
#Override
public boolean dispatchKeyEvent(KeyEvent event)
{
if (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)
{
// Do whatever you want
}
return super.dispatchKeyEvent(event);
}
Okay so finally the reason nothing worked was because my EditText had a width of 0. When I put width and height to 1. Setting visibility to View.INVISIBLE doesn't work in this case.
By the way, the three Listener (OnEditorActionListener, OnKeyListener and Overriding dispatchKeyEvent) get the callbacks. But I'll use OnEditorActionListener because it's the only one getting only one callback. The two others get several callbacks which is problematic.
I have a simple Android app that does some math on 2 numbers that the user inputs and returns the result.
Currently I have a 'calculate' button that needs to be pressed to do the math and return the value.
How can I get rid of this button and just get the app to run the math after the uses has changed either one of the 2 numbers?
Many thanks.
Assuming that you are using EditText-s for the input (because they could be SeekBar-s, who knows), add on each one of them a TextWatcher with this and after each change of one of them refresh the result
I used something like this for an EditText field that I wanted to be auto-updated after changing some other EditText fields:
myEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE)
{
calculateNewValue(); // Updates internal variables
// This part will hide the keyboard after input
InputMethodManager imm = (InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
return true;
}
return false;
}
});
This also hides the keyboard when you're done (thanks to a bit of help).
The calculateNewValue() updated the field like this:
private void calculateNewValue()
{
val = YourFormula()
myEditText.setText(String.format(yourFormat, val))
}
The details depend on what language you are using, but basically you could just run the calculation function whenever either one of the numbers is changed. There should be a way to override the function that is called when the data in either text box has changed.
Well, if both numbers start off with 0, you can either check to make sure neither or 0 or trigger the math when both text fields have received text changed events. I'm not sure what platform you are using so I can't give you much more info.