OmerN OmerN - 7 months ago 22
Java Question

Returning A Value From AlertDialog

I want to build a function that creates an AlertDialog and returns the string that the user entered, this the function I have for creating the dialog, how do I return the value?

String m_Text = "";
private String openDialog(String title) {
AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext());
builder.setTitle(title);

final EditText input = new EditText(view.getContext());
input.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL);
builder.setView(input);

builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
m_Text = input.getText().toString();
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});

builder.show();

// return string
}

Answer

Before going to the solution, I would like to explain a few things that you might have overlooked.

When you display your AlertDialog your code keeps running and does not wait for it to finish (e.i the openDialog() call continues executing without waiting for the AlertDialog to return something), that's why you have got the onClickListeners for handling your callbacks (express what you should do when the user clicks on the dialog ok button or dismiss it).

One clean way to achieve what you want is to create a functional interface (an interface having one method),and use it to handle your callbacks (make it return your String or whatever).

Ex:

interface OnOk{
     void hereIsYouText (String text);
}

And then you would alter you method to be like:

private void openDialog(String title, final OnOk onOk) {
    AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext());
    builder.setTitle(title);

    final EditText input = new EditText(view.getContext());
    input.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL);
    builder.setView(input);

    builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
         //Oi, look at this line!
         onOk.hereIsYourText(input.getText().toString());
    }
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        dialog.cancel();
        //TODO: you should handle this event as well! 
    }
});
builder.show();

}

You can use it like this:

openDialog("This is a title", 
           new OnOk(){
           @Override
           hereIsYourText (String text){
                //I ll log it
                Log.i("Texting",text);
           }});

Notice: I provided this answer to demonstrate how you could achieve what you asked for in an async fashion without completely altering your code. However I would recommend you to read about events, callbacks in order for you to handle those kind of issues in an elegant way.