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.
Related
I am making small application. I use EditText to summarize all data. It shows a few times, every time has own line. User is able to write short note next to time.
I have issue with soft keyboard. I would like it to have "ok" instead of enter. I mean, it shoul not do extra line. On enter, keyboard should close.
For now, I have something like this:
EtNotes.setOnKeyListener(new View.OnKeyListener()
{
#Override
public boolean onKey(View v, int keyCode, KeyEvent event)
{
if (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)
{
InputMethodManager imm = (InputMethodManager) getSystemService(
Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getApplicationWindowToken(), 0);
}
return false;
}
});
It closes keyboard, but it does extra line and that is the problem.
I have already tried to put:
android:imeOptions="actionDone"
in my layout xml file. Unfortunately it also didn't worked.
To sum up, I would like my keyboard don't do extra line and closes after enter button.
You have to return true in the branch where you handled the key input
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 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.
I have 14 edittext boxes that a user can change at will. When the text is changed in one of them, a softpad key press on the 'enter/next/done' key should re-run a calculation using the new text. I've tried onKey listener but it doesn't work on the soft keyboard, on;y the hard keypad. I've tried a textwatcher like onTextChanged but it reacts and runs the calculation when only a single digit is entered, before the user can input a two or more digit number. So... I hear the onEditorActionListener works on soft keypads to watch for the keypress, but I can't get the syntax right. Here's what I have:
In the onCreate method:
myEdittext1.setOnEditorActionListener(this);
...
myEdittext14.setOnEditorActionListener(this);
Then, outside the onCreate method, I have:
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event)
{ if (event.getKeyCode() == KeyEvent.FLAG_EDITOR_ACTION)
{ //do my calcs}
}
return(true);
}
The code gives me the foreced-close business. Any help would be greatly appreciated.
KeyEvent can be null. You need to check for this situation in your listener.
v The view that was clicked.
actionId Identifier of the action. This will be either the identifier you supplied, or EditorInfo.IME_NULL if being called due to the enter key being pressed.
event If triggered by an enter key, this is the event; otherwise, this is null.
onEditorAction is the appropriate way to listen for finish and Done soft keyboard actions.
so here's a working version:
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event)
{ if (event == null || event.getAction()==KeyEvent.ACTION_UP)
{ //do my calcs
return(true);//reset key event for next press
}
}
The enter key returns a 'null' in the event variable, thats why my version at the top of this post crashed.
Nick's code above worked well too, just remember to set the xml property android:imeOptions=actionDone" for all of the edittext boxes.
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.