I'm trying to override the soft input keyboard for a singular EditText field. I've mostly been following this excellent example -- setting the XML to inputType="text", and then, within the onCreate:
EditText amount = (EditText) findViewById(R.id.amount_edit_text);
final EditText amt = amount;
amount.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
showCustomKeyboard(v);
} else {
hideCustomKeyboard();
}
}
});
amount.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
showCustomKeyboard(v);
}
});
amount.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
EditText edittext = (EditText) v;
int inType = edittext.getInputType();
edittext.setInputType(InputType.TYPE_NULL);
edittext.onTouchEvent(event);
edittext.setInputType(inType);
return true;
}
});
This works for the most part -- clicking on the EditText brings up my custom keyboard, but there's always a jump. It's very quick, but it'll show my keyboard stacking on top of the standard keyboard, and then the standard keyboard will collapse and my keyboard will be left. And at times, it will arbitrarily not collapse and simply just stack...
Is there any way to override the standard keyboard with my own without this jump?
I ended up using a Runnable to close the standard keyboard before showing my custom keyboard. It's not quite perfect, but it doesn't stack the two keyboards like it used to. I'll keep looking for a better solution though.
within the else statement of my OnFocusChangeListener:
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
showCustomKeyboard(v);
}
}, 250);
((InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE))
.hideSoftInputFromWindow(v.getWindowToken(), 0);
Try to hide the softKeyboard when you are showing yours, using the following code:
InputMethodManager mgr = (InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE);
mgr.hideSoftInputFromWindow(amount.getWindowToken(), 0);
Related
My scenario is as it follows: I have a search fragment and in that fragment, I have 3 text fields(Search by name, by zip code and by distance). When the focus is applied on the "Search by name" field, the other 2 fields dissapear and the width of the selected field increases. My problem is that I can't lose focus of the first field and so, after I am done with writing the information, I can't use the other 2 fields.
What I am looking for is a way to lose focus of the fields when I press "enter" or when I press anywhere else on the screen but the text field.
Here is the code that I am running right now:
final EditText searchByName = (EditText) getActivity().findViewById(R.id.search_by_name);
final EditText searchByZipcode = (EditText) getActivity().findViewById(R.id.search_by_zipcode);
final EditText searchByDistance = (EditText) getActivity().findViewById(R.id.search_by_distance);
searchByName.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
/* When focus is lost check that the text field
* has valid values.
*/
if (hasFocus) {
searchByName.getLayoutParams().width=900;
searchByZipcode.setVisibility(View.INVISIBLE);
searchByDistance.setVisibility(View.INVISIBLE);
} else {
searchByName.getLayoutParams().width=405;
searchByZipcode.setVisibility(View.VISIBLE);
searchByDistance.setVisibility(View.VISIBLE);
}
}
});
searchByZipcode.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
/* When focus is lost check that the text field
* has valid values.
*/
if (hasFocus) {
searchByZipcode.getLayoutParams().width=700;
searchByName.setVisibility(View.INVISIBLE);
} else {
searchByZipcode.getLayoutParams().width=240;
searchByName.setVisibility(View.VISIBLE);
}
}
});
Inside your Activity Class , add this below method , it will work for you .It will hide keyboard and will clear focus anywhere outside you click in that one it will work .
#Override
public boolean onTouchEvent(MotionEvent event) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.
INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
return true;
}
It happens when the user dismisses the softkeyboard and then tries to click/gain focus on the EditText again, nothing happens only the cursor is shown - I want to show the keyboard again.
I've tried:
Using an onclick event
Using a focuschanged event
Changing properties of the EditText (focusable etc...)
Note: I am currently using Paranoid Android. The EditText is Multiline.
I found the solution, I just had to remove the following attribute from my EditText:
android:textIsSelectable="true"
Please start by omitting any requestFocus defined for your EditText.
there's a known bug that prevents keyboard from showning if the latter is set.
If that doesn't work for you, create a focus listener and in it programmatically open the virt keyboard:
editTxt.setOnFocusChangeListener(new OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if(hasFocus) {
// show keyboard
InputMethodManager imm = (InputMethodManager)this.getSystemService(Service.INPUT_METHOD_SERVICE);
imm.showSoftInput(editTxt, 0);
}
}
});
Here is a solution:
final InputMethodManager imm=(InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
EditText e= (EditText) findViewById(R.id.editText1);
e.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
imm.showSoftInput(e, InputMethodManager.SHOW_IMPLICIT);
}
});
e.setOnEditorActionListener(new OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
// TODO Auto-generated method stub
if(actionId==EditorInfo.IME_ACTION_GO){
imm.hideSoftInputFromWindow(e.getWindowToken(), 0);
//Do you work here
}
return false;
}
});
and the edittext will be:
<EditText
android:id="#+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:imeOptions="actionGo"/>
Found two solutions - please see selected answer
When the user clicks in a certain region of an EditText, I want to popup a dialog. I used onClick to capture the click. This partially works: the first time the user taps the EditText, the soft keyboard pops up and the dialog doesn't. Subsequent taps bring up the keyboard and then the dialog (and the keyboard disappears).
I suspect this has something to do with the EditText gaining focus.
Here's a code snip:
public class PrefixEditText extends EditText implements TextWatcher, OnClickListener
{
public PrefixEditText (Context context)
{
super (context);
setOnClickListener (this);
}
#Override
public void onClick(View v)
{
int selStart = getSelectionStart();
if (selStart < some_particular_pos)
bring_up_dialog();
}
}
IMPORTANT: I don't want to completely disable the normal EditText behavior. I want the user to be able to make region selections (for copy & paste). I probably still want it to gain focus (so I don't break the model when people with physical keyboards use the app). And it's ok for the click to set the cursor position. Thus, solutions that override onTouch and block all onTouch actions from the EditText will not work for me.
UPDATE I've discovered a bit more. If the EditText is gaining focus, onFocusChange gets called and onClick does not. If it already has focus, onClick gets called and onFocusChange does not.
Secondly, it's possible to hide the keyboard by calling
setInputType (InputType.TYPE_NULL);
Doing so in onFocusChange works - the keyboard never shows up. Doing so in onClick (assuming the keyboard was hidden before the click) apparently is too late - the keyboard shows up and then disappears.
The next idea to try would be to hide the keyboard during onTouch. However, I'm afraid to mess with that code - seems that whatever I figure out would be very fragile with respect to future versions of EditText.
Any thoughs on this?
May be this can work
EditText e = new EditText(context);
e.setOnFocusChangeListener(new OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
// TODO Auto-generated method stub
if(hasFocus)
{
//dialogue popup
}
}
});
or u can use e.hasFocus(); and then use e.setFocusable(false); to make it unfocus
/////////////// my code
e.setInputType(InputType.TYPE_NULL);
e.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
AlertDialog.Builder sa = new Builder(ctx);
sa.create().setOnDismissListener(new OnDismissListener() {
public void onDismiss(DialogInterface dialog) {
// TODO Auto-generated method stub
e.setInputType(InputType.TYPE_CLASS_TEXT);
}
});
sa.show();
}
});
try change capture click by onClick to onTouch
this.editText.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
//dialogue popup
}
return false;
}
});
try this if it can help u.first time the edittext will behave as a normal editttext and on condition u can show the dialog as needed
EditText editText;
mTim_edittext.setOnFocusChangeListener(new OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if(!hasFocus){
//statement
if(condition){
AlertDialog diaBox = Utils.showErrorDialogBox( "Term in Months Cannot be 0", context);
diaBox.show();
}
}
}
});
After lots of experiments, here are two working solutions! I tested them on my two devices - Nexus 7 running 4.2.1, Kyocera C5170 runing 4.0.4. My preference is Solution 2.
SOLUTION 1
For the first, the trick was to determine the cursor position in onTouch instead of onClick, before EditText has a chance to do it's work - particularly before it pops up the keyboard.
One additional comment: be sure to set android:windowSoftInputMode="stateHidden" in your manifest for the popup, or you'll get the keyboard along with the popup.
Here's the whole code:
public class ClickText extends EditText implements OnTouchListener
{
public ClickText (Context context, AttributeSet attrs)
{
super (context, attrs);
setOnTouchListener (this);
}
#Override
public boolean onTouch (View v, MotionEvent event)
{
if (event.getActionMasked() == MotionEvent.ACTION_DOWN)
{
int line = getLayout().getLineForVertical ((int)event.getY());
int onTouchCursorPos = getLayout().getOffsetForHorizontal (line, event.getX());
if (onTouchCursorPos < 10) // or whatever condition
showPopup (this); // or whatever you want to do
}
return false;
}
private void showPopup (final EditText text)
{
Intent intent = new Intent (getContext(), Popup.class);
((Activity)getContext()).startActivity (intent);
}
}
SOLUTION 2
This one is actually simpler and, I think, is better - fewer side effects.
Here, the trick is to let EditText do all its click processing and then override it asynchronously. The gist is: wait for the touch to "let go" - MotionEvent.ACTION_UP - and then instead of doing your action right then, post a Runnable to the event queue and do your action there.
The whole code:
public class ClickText extends EditText implements OnTouchListener
{
public ClickText (Context context, AttributeSet attrs)
{
super (context, attrs);
setOnTouchListener (this);
}
#Override
public boolean onTouch (View v, MotionEvent event)
{
switch (event.getActionMasked())
{
case MotionEvent.ACTION_UP:
{
post (new Runnable ()
{
// Do this asynch so that EditText can finish setting the selectino.
#Override
public void run()
{
int selStart = getSelectionStart();
int selEnd = getSelectionEnd();
// If selStart is different than selEnd, user has highlighed an area of
// text; I chose to ignore the click when this happens.
if (selStart == selEnd)
if (selStart >= 0 && selStart < 10) // or whatever range you want
showPopup (this);
}
});
break;
}
}
return false;
}
private void showPopup (final EditText text)
{
Intent intent = new Intent (getContext(), Popup.class);
((Activity)getContext()).startActivity (intent);
}
}
use this below code snippet
this.editText.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
//dialogue popup
}
return false;
}
});
I have an activity where there is an EditText and on enter key search results are shown, so what I simply want to do is to close the keyboard when search results are about to show to prevent the user from having to do it. However if the user wants to refine his search the keyboard should open back up if he taps into the EditText again.
This has been more difficult than I imagined, I've been search and tried a few things most don't even close the keyboard on my HTC, one method where the InputType is set to INPUT_NULL closes the keyboard but it doesn't open afterwards.
Any suggestions on how to do this?
#Override
public boolean onQueryTextSubmit(String query) {
// Your search methods
searchView.clearFocus();
return true;
}
Straight to the point and clean.
The right way to do this:
set imeOptions to "actionSearch"
initialize listeners for input and search button(if provided)
searchEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
performSearch();
return true;
}
return false;
}
});
view.findViewById(R.id.bigSearchBar_button).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
performSearch();
}
});
Hide keyboard when user clicks search. To ensure that keyboard won't show when user minimizes and restores Activity you have to remove focus from EditText
private void performSearch() {
searchEditText.clearFocus();
InputMethodManager in = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
in.hideSoftInputFromWindow(searchEditText.getWindowToken(), 0);
... perform search ...
}
I belive this code snippet will close the keyboard:
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(myEditText.getWindowToken(), 0);
if not try this one:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
let me know if these work
the editText is not losing focus in my app when I click out of it, it has the orange border all time and that black line cursor..
I did this a LinearLayout according to this surrounding the editText:
Stop EditText from gaining focus at Activity startup
so it doesn't get focus on start of the app..
this is my code:
final EditText et = (EditText)findViewById(R.id.EditText01);
final InputMethodManager imm = (InputMethodManager) getSystemService(
INPUT_METHOD_SERVICE);
et.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
imm.showSoftInput(et, InputMethodManager.SHOW_IMPLICIT);
}
});
et.setOnFocusChangeListener(new View.OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasfocus) {
if(hasfocus) {
imm.showSoftInput(et, InputMethodManager.SHOW_IMPLICIT);
} else {
imm.hideSoftInputFromWindow(et.getWindowToken(), 0);
}
}
});
But, it doesn't seem to be calling the onFocusChange when I click anywhere outside the editText!
It's simple. You can put the following in LinearLayout or any other else:
android:focusableInTouchMode="true"
Override Activity.dispatchTouchEvent():
#Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
View view = getCurrentFocus();
if (view != null && view instanceof EditText) {
Rect r = new Rect();
view.getGlobalVisibleRect(r);
int rawX = (int)ev.getRawX();
int rawY = (int)ev.getRawY();
if (!r.contains(rawX, rawY)) {
view.clearFocus();
}
}
}
return super.dispatchTouchEvent(ev);
}
That way, whenever someone clicks anywhere, you have control, and it's at only one point in code.
Create an onClick listener, possibly in your XML layout to listen for clicks in the background LinearLayout. From here you can call .clearFocus() on your EditText after you make it an instance variable of the activity you are working in.
You can remove the focus from the EditText, by setting the focus to other field by calling the method.
Suppose I have set the focus to back button on click of done button, then call the method on back button inside done button click listener.
And your problem is solved.
back.requestFocusFromTouch();