Dismiss android preferences dialog on Keyboard ACTION_DONE press - android

I would like to be able to close the editpreference dialog (as shown here http://twitpic.com/18ttdp) by pressing the 'Done' button on the keyboard.
Currently, pressing 'Done' just dismisses the keyboard but leaves the dialog.
In other parts of my application I use code similar to the following to intercept the 'Done' key press and execute actions in my activity:
text.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
//do stuff here
return true;
}
return false;
}
});
However, I am unsure of how to do achieve this same effect in my preference activity or layout xml.

Instead of adding the listener there, you should do something similar to this:
getDialog().setOnKeyListener(new OnKeyListener() {
#Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
dialog.dismiss();
return true;
}
});
This code will dismiss the dialog when a key is pressed.

I had the same problem, this is how I solved it:
// edit text to get input
final EditText input = new EditText(this);
//input.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
input.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_IME_MULTI_LINE);
alert.setView(input);
// ok button
alert.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// do stuff
}
});
For my needs, the input was a number (hence the commented out line) but if you want text use what's there.

Here is how I solved it:
final EditTextPreference namePref = (EditTextPreference) findPreference("name");
namePref.getEditText().setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if(actionId == EditorInfo.IME_ACTION_DONE) {
namePref.onClick(null, DialogInterface.BUTTON_POSITIVE);
namePref.getDialog().dismiss();
return true;
}
return false;
}
});
But you may want to consider subclassing EditTextPreference instead, since this onClick call is a hack, and its implementation may change in the future.

Related

How to use EditText onClick method while remaining focused

I have an EditText that has a ListPopupWindow attached to it with recent search queries listed. When a user clicks the EditText, the popup should show, then when the user starts typing, the popup should disappear.
This is mostly working using OnFocusChangeListener, OnTextChangedListener, and OnEditorActionListener. However, if a user has clicked on the EditText, began to type, then clicks the EditText again, I need the popup to come back up. I have tried using an OnClickListener instead of an OnFocusChangeListener but can never get the popup to show with an OnClickListener.
How can I get the ListPopUpWindow to show when the use clicks the EditText if it already has focus?
searchBox.setOnFocusChangeListener(new View.OnFocusChangeListener() {
public void onFocusChange(View v, boolean gainFocus) {
//onFocus
if (gainFocus) {
popUpWindow.show();
}
}
});
To dismiss popup once user start typing in EditText field
searchBox.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
popUpWindow.dismiss();
}
});
To clear focus, dismiss popup, and execute search
searchBox.setOnEditorActionListener(new TextView.OnEditorActionListener() {
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if ((actionId & v.getImeOptions()) == actionId) {
if (event != null && event.getAction() == KeyEvent.ACTION_DOWN) {
if (searchBox.getText().toString().length() == 0) return true;
searchBox.clearFocus();
popUpWindow.dismiss();
fetchResults();
Util.hideKeyboard(v);
return true;
}
}
return false;
}
});
You can try replacing the focus change listener with an on touch listener and showing the popup when a MOTION_UP event occurs:
editText.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if ((event.getAction() == MotionEvent.ACTION_UP) {
// Show popup here
}
return false;
}
});
I found the problem. It turns out I wasn't actually using an EditText object, but rather a custom class called MaterialEditText that provides a wrapper around an EditText object to give it Material UI features. The class passes the listeners I had been using onto it's EditText member, however, it was not doing so for either OnClickListener or OnTouchListener, so these listeners were never getting set for the EditText object. Once I added methods to pass these listeners on to the EditText object, I fixed my issue by keeping the code listed above and adding the following:
searchBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Show Popup
}
});

setOnKeyListener not responding

I am new to Android and working through a to do list example from a book. I have one Activity which is displaying an EditText and a ListView beneath it. There is an onKey event which should add the text from the EditText to the ListView and clear the EditText. However, when I hit Enter on the keyboard all that happens is a new line is added to the EditText and nothing is added to the ListView.
The onCreate code is:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_to_do_list);
// Get UI references
ListView myListView = (ListView)findViewById(R.id.myListView);
final EditText myEditText = (EditText)findViewById(R.id.myEditText);
myEditText.setText("test");
// Create ArrayList to store To Do items
final ArrayList<String> toDoItems = new ArrayList<String>();
// Create ArrayAdapter to bind items to List View
final ArrayAdapter<String> aa;
aa = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
toDoItems);
// Bind Adapter to List View
myListView.setAdapter(aa);
myEditText.setOnKeyListener(new View.OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN)
if ((keyCode == KeyEvent.KEYCODE_DPAD_CENTER) ||
(keyCode == KeyEvent.KEYCODE_ENTER)) {
toDoItems.add(0, myEditText.getText().toString());
aa.notifyDataSetChanged();
myEditText.setText("");
return true;
}
return false;
}
});
}
I've added the myEditText.setText("test"); just to ensure the reference to myEditText is working, which it is. I've tried removing the if statements from the onKey event and it just doesn't appear to be registering key events at all. Can anyone advise what I'm doing wrong here?
You could try using a OnEditorActionListener instead:
http://developer.android.com/reference/android/widget/TextView.html#setOnEditorActionListener(android.widget.TextView.OnEditorActionListener)
You could set on the edittext in XML:
android:imeOptions="actionDone"
and then in code:
myEditText.setOnEditorActionListener(new EditText.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
// your action here
return true;
}
return false;
}
)};
Are you using the virtual keyboard?
In that case the problem is that an OnKeyListener only gets called by hardware buttons. Take a look here:
http://developer.android.com/reference/android/view/View.OnKeyListener.html
The first line says: Interface definition for a callback to be invoked when a hardware key event is dispatched to this view.
Perpaps something line this will solve your problem: Validating edittext in Android
I was able to get that same example to work by adding the following attribute to the EditText element android:inputType="text". This changed the software keyboard that came up for the user and included a Send button.
In the setOnKeyListener code, I changed it to the following:
myEditText.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_UP)
if (keyCode == KeyEvent.KEYCODE_ENTER)
{
todoItems.add(0, myEditText.getText().toString());
aa.notifyDataSetChanged();
myEditText.setText("");
return true;
}
return false;
}
});
Don't use KEYCODE_DPAD_CENTER as that's a hardware button for devices that had up, down, left, right arrows.
Following code solved such problem:
You just need to need to add addTextChangedListener like this.Rest is self- explanatory
editabltText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void afterTextChanged(Editable editable)
{
}
});
Instead of setOnKeyListener, try to implement setOnEditorActionListener. Hope this helps.
<EditText
android:id="#+id/search"
android:singleLine="true"
android:imeOptions="actionSearch">
try to add singleLine and imeOption attributes.

Override Dialog's OnBackPressed

How can I specifically override just the back button while within a dialog to finish the entire activity and not just the dialog.
Using setOnCancelListener and setOnDismissListener do not work because there are other times that I simply close the dialog without closing the whole activity behind it.
Edit
Thanks Shubayu that may work!
I was also able to access just the back button in a dialog through this function.
dialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
#Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK){
finish();
}
return false;
}
});
Override
public void onBackPressed ()
of the activity and put in the way you want the behavior in it. Also set a boolean from your dialog which you use inside onBackPressed() of the Activity. if the boolean is true, run the disabling part of the onBackPressed() code else don't.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK){
// your logic goes here
return true;
}
return super.onKeyDown(keyCode, event);
}
use the above code::
You can use : dialog.setOnCancelListener(.....)
first set dialog.setCancelable(true);
than you can place below code :
dialog.setOnCancelListener(new DialogInterface.OnCancelListener()
{
#Override
public void onCancel(DialogInterface dialog)
{
// add code backpress
}
});

No use after extend AlertDialog and rewrite dispatchKeyEvent method

I want to disable the global search key when display the alertDialog. So I extents the class and rewrite the method dispatchKeyEvent to catch the key message. But when I press search key in the AlertDialog window, it cannot catch the key event. Why?
Here is the code in the new dispatchKeyEvent method:
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
if(event.getKeyCode() == KeyEvent.KEYCODE_SEARCH)
return true;
return super.dispatchKeyEvent(event);
}
I found the way to solve this. Not to extend the AlertDialog but extend the Builder instead. And in the constructor write the code below:
setOnKeyListener(new OnKeyListener() {
#Override
public boolean onKey(DialogInterface dialog, int keyCode,
KeyEvent event) {
if(event.getKeyCode() == KeyEvent.KEYCODE_SEARCH)
return true;
return false;
}
});
And this can catch the global search key and drop it.

Knowing when Edit text is done being edited

How do I know when my edit text is done being edited? Like when the user selects the next box, or presses the done button on the soft keyboard.
I want to know this so I can clamp the input. It looks like text watcher's afterTextChanged happens after each character is entered. I need to do some calculations with the input, so I would like to avoid doing the calculation after each character is entered.
thanks
By using something like this
meditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
switch (actionId){
case EditorInfo.IME_ACTION_DONE:
case EditorInfo.IME_ACTION_NEXT:
case EditorInfo.IME_ACTION_PREVIOUS:
yourcalc();
return true;
}
return false;
}
});
EditText inherits setOnFocusChangeListener which takes an implementation of OnFocusChangeListener.
Implement onFocusChange and there's a boolean parameter for hasFocus. When this is false, you've lost focus to another control.
EDIT
To handle both cases - edit text losing focus OR user clicks "done" button - create a single method that gets called from both listeners.
private void calculate() { ... }
btnDone.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
calculate();
}
});
txtEdit.setOnFocusChangeListener(new OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if(!hasFocus)
calculate();
}
});
Using an EditText object xml defined like this:
<EditText
android:id="#+id/create_survey_newquestion_editText_minvalue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:ems="4"
android:imeOptions="actionDone"
android:inputType="number" />
We can capture its text i) when the user clicks the Done button on the soft keyboard (OnEditorActionListener) or ii) when the EditText has lost the user focus (OnFocusChangeListener) which now is on another EditText:
/**
* 3. Set the min value EditText listener
*/
editText= (EditText) this.viewGroup.findViewById(R.id.create_survey_newquestion_editText_minvalue);
editText.setOnEditorActionListener(new OnEditorActionListener()
{
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event)
{
String input;
if(actionId == EditorInfo.IME_ACTION_DONE)
{
input= v.getText().toString();
MyActivity.calculate(input);
return true; // consume.
}
return false; // pass on to other listeners.
}
});
editText.setOnFocusChangeListener(new View.OnFocusChangeListener()
{
#Override
public void onFocusChange(View v, boolean hasFocus)
{
String input;
EditText editText;
if(!hasFocus)
{
editText= (EditText) v;
input= editText.getText().toString();
MyActivity.calculate(input);
}
}
});
This works for me. You can hide the soft keyboard after made the calculations using a code like this:
private void hideKeyboard(EditText editText)
{
InputMethodManager imm= (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
}
Edit: added return values to onEditorAction
I have done this simple thing, when focus is shifted from edit text get the text. This will work if user shifts the focus to select other views like a button or other EditText or any view.
editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
EditText editText = (EditText) v;
String text = editText.getText().toString();
}
}
});
To be more highlevel you may use TextWatcher's afterTextChanged() method.

Categories

Resources