Hi I'm trying to override IME action to show search on virtual keyboard. My EditText is in the control that is placed onto the activity.
Here is what I have:
<EditText android:id="#+id/txtSearch"
android:textSize="18dp"
android:textColor="#color/main_text_black"
android:layout_width="247dp"
android:layout_height="fill_parent"
android:imeOptions="actionSearch"
android:gravity="center_vertical"
android:singleLine="true"
android:background="#null"
android:layout_alignParentLeft="true"
android:layout_marginLeft="38px" />
In Code I have this listener set on the EditText:
#Override
public boolean onEditorAction(TextView view, int arg1, KeyEvent arg2) {
if((arg1 == EditorInfo.IME_ACTION_SEARCH) {
for(OnSearchListener listener : _listeners) {
listener.OnSearch(view, getSearchString());
}
}
InputMethodManager imm =
(InputMethodManager)_context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
return false;
}
arg1 always comes back as 0 when I press the enter key, which is "unidentified". I also tried different keyboards like sendMessage and none of them work neither. What's going on?
Thank you in advance!
You need to specify android:inputType="text" attribute in xml file.
updated to droid 2.2 and it started working. Horrible bug!
Related
here' the code
I have two edit Text in a row in my lay out,and when I touch next on keyboard it does not change the focus.
the setOnEditorActionListener does not work till i add extra editText
<EditText
android:id="#+id/firstText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:imeOptions="actionNext"
android:inputType="numberDecimal"
/>
<EditText
android:id="#+id/secondText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:imeOptions="actionDone"
android:inputType="numberDecimal"
/>
code:
firstText.setOnNextActionListener(new CallBack<KeyEvent>() {
#Override
public void call(KeyEvent data) {
secondText.requestEditTextFocus();
}
});
Give one value into edittext in xml file ..
android:singleLine="true"
You can try these
android:nextFocusDown="#+id/secondText"
android:nextFocusLeft="#+id/secondText"
android:nextFocusRight="#+id/secondText"
android:nextFocusUp="#+id/secondText"
Show below three ways, you can got you want Using any one of them
inputType ="actionNext" attribute
or
android:imeOptions="actionNext"
or
android:singleLine="true" and
android:nextFocusDown="#+id/secondText"
on your .xml you can do this.
If you want to do it programmatically in your activity or fragment then try below:-
firstText.setOnEditorActionListener(new OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event){
if (actionId == EditorInfo.IME_ACTION_NEXT) {
secondText.requestEditTextFocus();
return true; // Focus will do whatever you put in the logic.
}
return false; // Focus will change according to the actionId
}
});
I have tested with set Programmtically with changes secondText.requestEditTextFocus(); to secondText.requestFocus(); and its working fine.
Please show below Screenshotes
I have several EditText in my app, and when the "Done" key is clicked the soft keyboard is hidden. This does not happen with AutocompleteTextView.
Any idea why? Is there anything more to do to get the same behaviour with AutocompleteTextView?
<AutoCompleteTextView
android:id="#+id/autoCompleteTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_below="#id/search_zip"
android:layout_toLeftOf="#id/submit"
android:paddingLeft="10dp"
android:hint="#string/city_or_zip"
android:background="#drawable/bt_grey"
android:inputType="text"/>
android:imeOptions="actionDone"
or in java code:
InputMethodManager in = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
In my case setOnEditorActionListener was issue. So I removed below code :
searchEditText?.setOnEditorActionListener { v, actionId, event ->
if (EditorInfo.IME_ACTION_DONE == actionId) {
return#setOnEditorActionListener true
} else
return#setOnEditorActionListener false
}
I'm working on an Android app and I've got 2 editviews and a label. The user can enter 2 values and the label shows some calculation using input from the editviews. What I want is the following;
user enters either value with soft-keyboard
user presses "Return" softkey
editview should lose focus
the soft-keyboard should disappear
textview label should be recalculated
Now, the v.clearFocus only seems to works when there is another widget that can can get focus(?), so I've also added a dummie zero-pixel layout that can 'steal' the focus from the first editview. The Return key works now, but when the user switches focus from edit1 to edit2 by simply tapping then HideKeyboard() crashes. I've tried checking if inputMethodManager==null but that didn't help.
This all feels like I'm hacking to trick Android into doing some common UI behaviour, so I can't help but think that I'm overlooking something here.
Any help would be greatly appreciated. Btw I know this is similar to this question: How to lose the focus of a edittext when "done" button in the soft keyboard is pressed?
But I've tried that and it doesn't work.
So my layout xml is this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical" >
<!-- Dummy control item so that first textview can lose focus -->
<LinearLayout
android:focusable="true"
android:focusableInTouchMode="true"
android:layout_width="0px"
android:layout_height="0px"/>
<EditText
android:id="#+id/editTest1"
android:layout_width="250px"
android:layout_height="wrap_content"
android:inputType="numberDecimal"
android:imeOptions="actionDone" >
</EditText>
<EditText
android:id="#+id/editTest2"
android:layout_width="250px"
android:layout_height="wrap_content"
android:inputType="numberDecimal"
android:imeOptions="actionDone" >
</EditText>
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="test123" />
</LinearLayout>
And the source is this:
public class CalcActivity extends Activity implements OnFocusChangeListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tab2_weight);
EditText testedit = (EditText) findViewById(R.id.editTest1);
testedit.setOnFocusChangeListener(this);
testedit.setOnEditorActionListener(new OnEditorActionListener() {
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if(actionId==EditorInfo.IME_ACTION_DONE){
//Clear focus here from edittext
Log.d("test app", "v.clearFocus only works when there are other controls that can get focus(?)");
v.clearFocus();
}
return false;
}
});
}
public void hideSoftKeyboard() {
InputMethodManager inputMethodManager = (InputMethodManager) this.getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), 0);
}
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus == false) {
Log.d("unitconverter", "onFocusChange hasFocus == false");
// update textview label
TextView bla = (TextView) findViewById(R.id.textView1);
bla.setText(String.format("%s + %s", (((EditText) findViewById(R.id.editTest1)).getText()), (((EditText) findViewById(R.id.editTest2)).getText())));
// hide keyboard
hideSoftKeyboard();
}
}
}
I'm trying to deactivate the soft keyboard when using a NumberPicker to enter numerical values (for aesthetic reasons). This is my layout-xml-code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/linearLayout2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="30dp"
android:layout_marginTop="30dp" >
<NumberPicker
android:id="#+id/repetitionPicker"
android:layout_width="40dp"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="#string/repetitions_short_divider"
android:textAppearance="?android:attr/textAppearanceMedium" />
<NumberPicker
android:id="#+id/weightPicker"
android:layout_width="40dp"
android:layout_height="wrap_content"
android:layout_marginLeft="40dp" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="#string/pounds"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
<Button
android:id="#+id/saveButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="#string/save" />
</LinearLayout>
And finally this is the code where I try to block the keyboard in the onCreate()-method:
// hide keyboard
View.OnClickListener disableKeyBoardListener = new View.OnClickListener() {
public void onClick(View v) {
((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE))
.hideSoftInputFromWindow(v.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
};
((EditText) weightPicker.getChildAt(1)).setInputType(InputType.TYPE_NULL);
((EditText) repetitionPicker.getChildAt(1)).setInputType(InputType.TYPE_NULL);
((EditText) weightPicker.getChildAt(1)).setOnClickListener(disableKeyBoardListener);
//((EditText) repetitionPicker.getChildAt(1)).setOnClickListener(disableKeyBoardListener);
//weightPicker.setOnClickListener(disableKeyBoardListener);
//repetitionPicker.setOnClickListener(disableKeyBoardListener);
getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
Sadly, the soft keyboard still shows up when clicking on a NumberPicker. Any ideas?
Just found this and it works like a charm:
myNumberPicker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);
You can also set this in XML:
android:descendantFocusability="blocksDescendants"
Xml version of Andrew Webber's answer
android:descendantFocusability="blocksDescendants"
Example
<NumberPicker
android:id="#+id/your_numberpicker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants"/>
After reading through the com/android/internal/widget/NumberPicker.java source code i got to the following solution:
// Hide soft keyboard on NumberPickers by overwriting the OnFocusChangeListener
OnFocusChangeListener fcl = new OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
// Do nothing to suppress keyboard
}
};
((EditText) numberPicker.getChildAt(1)).setOnFocusChangeListener(fcl);
// Suppress soft keyboard from the beginning
((EditText) numberPicker.getChildAt(1)).setInputType(InputType.TYPE_NULL);
Just enhanced the #MaxVogler 's ans (so if wannt vote this vote #MaxVogler too) and make it a robust hack. Also we dont need to call setOnFocusChangeListener and setInputType. Only setFocusable to false will do.
Below is a helper api to enable/disable the feature
public static void enableNumberPickerManualEditing(NumberPicker numPicker,
boolean enable) {
int childCount = numPicker.getChildCount();
for (int i = 0; i < childCount; i++) {
View childView = numPicker.getChildAt(i);
if (childView instanceof EditText) {
EditText et = (EditText) childView;
et.setFocusable(enable);
return;
}
}
}
Here's another way to do it which enables the user still to edit a number if they want to - it just suppresses the soft keyboard initially. Use NumberPicker.setDescendantFocusability(FOCUS_BLOCK_DESCENDANTS) to suppress the soft keyboard when the interface first shows as per answers above. Then get your dialog or activity to implement View.OnTouchListener, call setOnTouchListener(this) on your NumberPicker, and in your implementation of onTouch(View v,MotionEvent e) reset the numberpicker descendant focusability to its normal value, then return false.
Returning false means that the touch is still processed by the NumberPicker, which means that if the user taps the edit box the soft keyboard comes up. This happens to be exactly what I wanted faced with the same problem - having the soft keyboard come up with the dialog when it first shows is displeasing as it shifts the dialog up after it appears.
public class GetBufferDialog extends DialogFragment implements View.OnTouchListener {
after creating the Dialog in the onCreateDialog() method and finding the NumberPicker:
m_oldFocus = m_numberpicker.getDescendantFocusability();
m_numberpicker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);
m_numberpicker.setOnTouchListener(this);
and here's the OnTouch method:
public boolean onTouch(View v, MotionEvent event) {
m_numberpicker.setDescendantFocusability(m_oldFocus);
return false;
}
Working code
Programatically :
mp.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);
XML:
android:descendantFocusability="blocksDescendants"
I don't know why it works, but setting OnClickListener which does nothing prevented keyboard from showing (Lollipop)
numberPicker.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
The simplest I found to work was :
numberPicker = (NumberPicker) myDialogView.findViewById(R.id.myViewId);
EditText numberPickerChild = (EditText) numberPicker.getChildAt(0);
numberPickerChild.setFocusable(false);
numberPickerChild.setInputType(InputType.TYPE_NULL);
If you only want to hide the software keyboard when loading the view with your number picker, but still want the users to be able to edit after the view loads, then you shouldn't block descendant focusability. Instead, just prevent the number picker from being the first focused item in your view.
See this answer for details.
Based on the above answer:
<!-- Dummy item to prevent Number Picker from receiving focus -->
<LinearLayout
android:focusable="true"
android:focusableInTouchMode="true"
android:layout_width="0px"
android:layout_height="0px"/>
<!-- :nextFocusUp and :nextFocusLeft have been set to the id of this component
to prevent the dummy from receiving focus again -->
<NumberPicker
android:id="#+id/number_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:nextFocusUp="#id/number_picker"
android:nextFocusLeft="#id/number_picker"/>
/**
* set focus to top level window
* disposes descendant focus
* disposes softInput
* #param context - activity context
* #param enable - state of focus
* */
public static void topLevelFocus(Context context, boolean enable){
if(Activity.class.isAssignableFrom(context.getClass())){
ViewGroup tlView = (ViewGroup) ((Activity) context).getWindow().getDecorView();
if(tlView!=null){
tlView.setFocusable(enable);
tlView.setFocusableInTouchMode(enable);
tlView.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
tlView.requestFocus();
}
}
}
* calling this:
will not block descendant focusability (numberpicker will be editable)
will hide soft input on create
before (processing input) getValue() will allow to get proper walue
This extension is nice to not forget how to do it and have readable code. It is little bit hiding implementation details, but in this case I believe it's acceptable:
fun NumberPicker.disableTextEditing(disable: Boolean) {
descendantFocusability = if (disable) FOCUS_BLOCK_DESCENDANTS else FOCUS_BEFORE_DESCENDANTS
}
In edittext, after typing 'Enter' key, system make a new line inside it. I'd like to focus on next edittext, no new line. how to code? my code in xml is below
<EditText
android:id="#+id/txtNPCode"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
android:layout_alignLeft="#+id/lblNPCode"
android:layout_below="#+id/lblNPCode"
android:layout_centerHorizontal="true"/>
<EditText
android:id="#+id/txtCNPCode"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
android:layout_alignLeft="#+id/lblCNPCode"
android:layout_below="#+id/lblCNPCode"
android:layout_centerHorizontal="true"/>
I also caputer key code in setOnKeyListener
tCNPCode.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if(keyCode == 66) {
Toast.makeText(S_PCode.this, "Enter Key", Toast.LENGTH_LONG).show();
//tNPCode.setFocusable(true);
}
return false;
}
});
You don't even have to use OnKeyListener. Simply add line android:singleLine="true" to your EditText. After this operation EditText behaves exactly like you want. So, in your particular case:
<EditText
android:id="#+id/txtNPCode"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
android:layout_alignLeft="#+id/lblNPCode"
android:layout_below="#+id/lblNPCode"
android:layout_centerHorizontal="true"
android:singleLine="true"
/>
<EditText
android:id="#+id/txtCNPCode"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
android:layout_alignLeft="#+id/lblCNPCode"
android:layout_below="#+id/lblCNPCode"
android:layout_centerHorizontal="true"
/>
solves the problem.
You have to use the requestFocus method. In your case it will be something like:
tCNPCode.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_ENTER) {
txtCNPCode.requestFocus();
}
return false;
}
});
The best way is to use one of the options for inputType, for example: android:inputType="textPersonName"
This will achieve the wanted effect. Check out the other options too, it'll save you some time in future :)
You shouldn't use android:singleLine="true", since it's deprecated. Here's what the documentations says about it:
This attribute is deprecated and is replaced by the textMultiLine
flag in the inputType attribute. Use caution when altering existing
layouts, as the default value of singeLine is false (multi-line
mode), but if you specify any value for inputType, the default is
single-line mode. (If both singleLine and inputType attributes are
found, the inputType flags will override the value of singleLine.).
Consider IME options, good description here http://androidcookbook.com/Recipe.seam;jsessionid=C824437B48F346E23FBE5828969029B4?recipeId=422 and documentation here http://developer.android.com/reference/android/widget/TextView.html#attr_android:imeOptions.
The only thing you need is add attribute android:imeOptions="actionNext" on each EditText. Keyboard appears with a Next key where Enter used to be and allows to navigate to the next EditText.
But order of "actionNext" is from top to bottom. For example, if you have horizontal layout:
<LinearLayout android:orientation="horizontal" >
<EditText android:id="#+id/et1" android:imeOptions="actionNext" />
<EditText android:id="#+id/et2" android:imeOptions="actionNext" />
</LinearLayout>
et2 never get focus. You should fix it in the code:
et1.setOnEditorActionListener(new OnEditorActionListener()
{
#Override
public boolean onEditorAction(TextView v, int actionId,
KeyEvent event)
{
switch (actionId)
{
case EditorInfo.IME_ACTION_NEXT:
boolean result = false;
TextView v1 = (TextView) v.focusSearch(View.FOCUS_RIGHT);
if (v1 != null)
result = v1.requestFocus(View.FOCUS_RIGHT);
else if (!result)
{
v1 = (TextView) v.focusSearch(View.FOCUS_DOWN);
if (v1 != null)
result = v1.requestFocus(View.FOCUS_DOWN);
}
if (!result)
v.onEditorAction(actionId);
break;
default:
v.onEditorAction(actionId);
break;
}
return true;
}
});
Original link: https://groups.google.com/forum/?fromgroups=#!topic/android-developers/OykOG6XtE8w
Use Single Line of Code (Java)
tCNPCode.setSingleLine(true);
Kotlin
tCNPCode.isSingleLine = true
It will navigate to the next item on Enter press
Just set the maximum number of line to the EditText box in xml layout file:
android:maxLength="1"