I would like an AlertDialog with an EditText field in it to accept input. This in itself is pretty straight-forward. However there are a few "obvious" features that I would like as fallout from this request. I'll take them one-by-one. I am looking for anyone that has a simpler solution to these things. I am guessing the solution is, "Write your own custom dialog you lazy bum."
AlertDialog with an EditText
final EditText input = new EditText(context);
final AlertDialog dlg = new AlertDialog.Builder(this).
setTitle("Title").
setView(input).
setCancelable(false).
setPositiveButton(android.R.string.ok, new OnClickListener()
{
#Override
public void onClick(final DialogInterface dialog, final int which)
{
/* Handle ok clicked */
dialog.dismiss();
}
}).
setNegativeButton(android.R.string.cancel, new OnClickListener()
{
#Override
public void onClick(final DialogInterface dialog, final int which)
{
/* Handle cancel clicked */
dialog.dismiss();
}
}).create();
dlg.show();
Yay, works great. It'd sure be nice if that input field got focused right away (and show the keyboard), right?
AlertDialog with focused EditText
The following code would be after create() and before dlg.show()
/** This requires API Level 8 or greater. */
dlg.setOnShowListener(new OnShowListener()
{
#Override
public void onShow(final DialogInterface dialog)
{
input.requestFocus();
((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(input, 0);
}
});
Nice job... I guess. Now that I have this focused input it'd be nice if it respected the inputs IME option...
AlertDialog with focused EditText with a custom IME Option
input.setImeOptions(EditorInfo.IME_ACTION_DONE);
input.setOnEditorActionListener(new OnEditorActionListener()
{
#Override
public boolean onEditorAction(final TextView v, final int actionId, final KeyEvent event)
{
/** Same code here that goes in the dialog.setPositiveButton OnClickListener */
dlg.dismiss();
return true;
}
});
Now that's really not a great solution (repeated code) but it works...
Do people have a better way of solving this problem, or is it really that rare to ask a user for a small piece of information in a dialog, or am I just a winer and should go write my own dialog?
As per comments on the OP:
You do not have to have such repeated code in the OnEditorActionListener. Instead of repeating the code, you can tell the OS to click the "Ok" button when it is activated.
Something like this:
public boolean onEditorAction(final TextView v, final int actionId, final KeyEvent event) {
dlg.getButton(DialogInterface.BUTTON_POSITIVE).performClick(); // Click OK button
return true;
}
Overall I would say you are taking the right approach (documentation about collecting information through dialogs). As I mentioned in a comment, the OS uses an AlertDialog w/ EditText for adding dictionary words (to the user dictionary), so this is an expected functionality in the OS.
You can always switch to an Activity with Theme.Dialog theme or a DialogFragment which gives you a lot more freedom in tuning your widgets. AlertDialogs are probably better for displaying information. Hope this helps.
Related
I would like to display an ok cancel dialog to the user and I would like to know if use pressed ok, cancel, or if he chose to just dismiss the dialog by clicking elsewhere on the screen or pressing back button.
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
final EditText input = new EditText(MainActivity.this);
builder.setView(input);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
// ok stuff
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
// cancel stuff
}
});
builder.setOnDismissListener(new DialogInterface.OnDismissListener()
{
#Override
public void onDismiss(DialogInterface dialog)
{
//dismiss stuff
}
});
builder.show();
The problem here is that whenever user presses ok button, dismiss listener gets triggered right after.Is there any way to not trigger dismiss listener if user presses button?
I do realize that I can use a boolean flag, but I am hoping that there is actually an elegant solution.
I am not searching for solution on how to prevent dialog from being dismissed. I am searching for solution on how to prevent dismiss listener from being triggered when ok button is pressed and dialog gets dismissed.
I think what you need is setOnCancelListener().
setOnDismissListener() will be called for any reason. It means if dialog will disappear from the screen either due to Ok/Cancel button press or screen touch or back button or home button press, setOnDismissListener() will be called.
Sets the callback that will be called when the dialog is dismissed for
any reason.
If you are interested in listening for all cases where the dialog is
dismissed and not just when it is canceled, see setOnDismissListener
So workaround it what you have mentioned, check using some boolean flags and handle it.
You can again show that dialog after being dismissed!
You can try CustomViewDialog by using
LayoutInflater myDialog = getLayoutInflater();
View convertView = (View) myDialog.inflate(R.layout.MyLayoutXmlFile, null);
Also don't use positive or negative buttons only use buttons in the dialog layout.
My app begin with a users login.
when the user push the "Enter" button (after he mark himself on the gridview that gets data from sqlite). The app open alertdialog by inflater.
if (gridView.isClickable()){
Toast.makeText(getApplicationContext(), "Waiter selected", Toast.LENGTH_LONG).show();
LayoutInflater inflater = getLayoutInflater();
View dialogLayout = inflater.inflate(R.layout.password_dialog, null);
AlertDialog.Builder passwordDialog = new AlertDialog.Builder(MainActivity.this);
The XML file(layout) is only with an editext, on this editext the user needs to fill in
his own password:
passwordDialog.setTitle(getString(R.string.get_id_uniq));
passwordDialog.setMessage(getString(R.string.enter_id));
passwordDialog.setView(dialogLayout);
passwordDialog.setPositiveButton(getString(R.string.next),
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
password = input.getText().toString();
and now the problem, when the user click on the editext the keyboard open and
then he puts his password, when he finish and press on the "Go" button on
the keyboard,the keyboard close but that not enough cause now he need to push again on the alertdialog button and only then the app will check if the password is correct and will move him to the next activity.
i tried to use -
android:imeOptions="actionNext"
and also the "Done", "Go" & "Send" , none of them help.
how do i prevent the double click on 2 different buttons and send the data from the keyboard button and skip the need to push the dialog button?
You can do it like this:
change dialog type to AlertDialog, instead of AlertDialog.Builder - that will allow you to dismiss (close) your dialog.
use setOnEditorActionListener for you input, instead of setPositiveButton
Call dialog.dismiss(); When user click done on keyboard.
It should look something like that:
AlertDialog dialog = new AlertDialog.Builder(this).create();//note dialog's type
dialog.setTitle("Let's check it");
EditText input = new EditText(this);
dialog.setView(input);//assume this is your input
input.setOnEditorActionListener(new TextView.OnEditorActionListener() {
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if(actionId == EditorInfo.IME_ACTION_DONE){
//What to do when user clicked Done button
Log.i("user's password:", v.getText().toString());//v.getText().toString(); is what's user has entered
dialog.dismiss();//close Alert Dialog
return true;
}
return false;
}
});
The below alert dialog requires me to click whichever button I click twice in order to close the dialog window and after an hours googling, I can't find the answer. I am sure it is staring me in the face but I just can't see it.
Edit: More searching has led me to believe the dialog is actually opened twice and it is occuring here:
asset_id_text_view.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
showAssetIDDialog();
return true;
}
});
Edit: started out with dialog.dismiss(); and some googling suggested trying dialog.cancel(); Neither of which were successful for me.
public void showAssetIDDialog() {
// TODO Auto-generated method stub
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
CreateTicketActivity.this);
// set title
alertDialogBuilder.setTitle("Enter Asset ID");
alertDialogBuilder.setCancelable(true).setMessage(
"How would you like to proceed?");
alertDialogBuilder.setPositiveButton("Enter text",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
//enterTextDialog();
dialog.cancel();
}
});
alertDialogBuilder.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
// create alert dialog
AlertDialog alertDialog = alertDialogBuilder.create();
// show it
alertDialog.show();
}
cancel() - Cancel the dialog. This is essentially the same as calling dismiss(), but it will also call your DialogInterface.OnCancelListener (if registered).
just cancel() will cancel the listener registerred on DialogInterface.
dismiss() - Dismiss this dialog, removing it from the screen. This method can be invoked safely from any thread. Note that you should not override this method to do cleanup when the dialog is dismissed, instead implement that in onStop().
Use dialog.dismiss() for your solution
http://developer.android.com/guide/topics/ui/dialogs.html#DismissingADialog
Please refer the above link for further query.
So it looks like the problem was indeed with the OnTouchListener
The code was doing what I had asked it to do and that was to open an AlertDialog every time there was a motionEvent. That makes at least 2 times for every touch
by including a switch statement, I was able to only trigger the opening of the alertDialog when the screen was pressed and not also when the screen was released as follows:
asset_id_text_view.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
showAssetIDDialog();
break;
default:
break;
}
});
You can call dialog.dismiss() in the OnClickListener of the buttons to close the dialog.
Use dialog.dismiss();
Dismiss this dialog, removing it from the screen. This method can be
invoked safely from any thread.
alertDialogBuilder.setPositiveButton("Enter text",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
//enterTextDialog();
dialog.dismiss();
}
});
I wonder if there is any native support for andengine or ADK to ask question-toasts? For example if I press the back button, I want some box to popup asking if I really want to quit the application and give me the option to answer yes or no.
Better to use alert dialog use this code, hope work same like that
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
switch(keyCode)
{
case KeyEvent.KEYCODE_BACK:
AlertDialog.Builder ab = new AlertDialog.Builder(AlertDialogExampleActivity.this);
ab.setMessage("Are you sure?").setPositiveButton("Yes", dialogClickListener)
.setNegativeButton("No", dialogClickListener).show();
break;
}
return super.onKeyDown(keyCode, event);
}
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
switch (which){
case DialogInterface.BUTTON_POSITIVE:
//Yes button clicked
break;
case DialogInterface.BUTTON_NEGATIVE:
//No button clicked
break;
}
}
}
You found your solution that is good but for the above answer you have to use AndEngine functionality. If you are working with AndEngine then you have to develop all the things with AndEngine power.
So for your solution you have to create one child scene which popup when user press device back button like in the following code snippet.
class DialogBox extends Scene{
DialogBox(...){
}
// you have to include all the functionality that your dialog box should contain
}
You have to set above dialog box as child of your main scene like in the following manner on the back event of user.
mScene.setAsChildScene(new DialogBox(...));
I prefer this way if I am developing a game.
I am making an application and I have added an EditText in my layout.
What I'm trying to achieve is that when EditText is selected should open a dialog box, with some general text and an OK button. Which method can I use to accomplish this?
You must try some thing like this
searchtext.setOnKeyListener(new OnKeyListener()
{
public boolean onKey(View v, int keyCode, KeyEvent event)
{
if (event.getAction() == KeyEvent.ACTION_DOWN)
{
showDialog();
}
}
};
and here goes showDialog() code
private void showDialog()
{
final AlertDialog.Builder Main_Dialog = new AlertDialog.Builder(this);
final EditText input = new EditText(this);
input.setPadding(10, 10, 10, 10);
input.setText(ipAddress);
Main_Dialog.setView(input);
Main_Dialog.setTitle("Enter IP Address:");
Main_Dialog.setPositiveButton("Ok", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int whichButton)
{
//Do whatever
}
});
Main_Dialog.show();
}
If I'm reading your dilemma correctly, you'd set an OnFocusChangeListener for the EditText. Something like the following snip.
EditText e = new EditText(this);
e.setOnFocusChangeListener
(
new OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (v.hasFocus()) {
showDialog(COOL_DIALOG);
}
}
}
);
Note, this seems like a somewhat odd user interaction. Why not just have them use the EditText for what it was made for? If you really want to do this, I'd suggest using a regular TextView or Button and use a click handler to pop the dialog. This would create a more "expected" interaction for the user.
You mean you want to display the dialog when your EditView gets focus? I think overriding View.onFocusChanged() would be the way to go. If you want to track the detailed input into EditText, implement TextWatcher and use TextView.addTextChangedListener() to add it to the EditText instance.