3

I have decided that I wanted to create some custom dialog classes that could be generically used by different Activities in different situations. To be specific, I created a dialog that contains a single EditText box and a title like this:

public class EditTextDialogFragment extends DialogFragment {

    // Factory method to create a new EditTextDialogFragment 
    public static EditTextDialogFragment newInstance( int title, int defaultText ) {
        EditTextDialogFragment frag = new EditTextDialogFragment( );
        Bundle args = new Bundle( );
        args.putInt( "title", title );
        args.putInt( "defaultText", defaultText );
        frag.setArguments( args );
        return frag;
    }

    // Set title and default text
    @Override
    public Dialog onCreateDialog( Bundle savedInstanceState ) {
        // Set an EditText view to get user input
        EditText inputView = new EditText( getActivity( ) );
        inputView.setHint( getArguments( ).getInt( "defaultText" ) );

        AlertDialog.Builder builder = new AlertDialog.Builder( getActivity( ) )
        .setIcon( android.R.drawable.ic_dialog_alert )
        .setTitle( getArguments( ).getInt( "title" ) )
        .setPositiveButton( R.string.ok, ( DialogInterface.OnClickListener )getActivity( ) )
        .setNegativeButton( R.string.cancel, ( DialogInterface.OnClickListener )getActivity( ) )
        .setView( inputView );

        return builder.create( );
    }
}

Note also that I'm doing this using DialogFragments as suggested in the most recent Android SDK.

Anyway, the idea is that, from any Activity I could make a call like this:

        EditTextDialogFragment etdf = EditTextDialogFragment.newInstance( R.string.add_new_term, R.string.term_name );
        etdf.show( getSupportFragmentManager( ), "new_term" );

And as long as I implement DialogInterface.OnClickListener in the Activity, I'll get a callback when the user finishes with the dialog. So I have this method in my Activity:

@Override
public void onClick( DialogInterface dialog, int whichButton ) {

    if ( whichButton == DialogInterface.BUTTON_POSITIVE ) {
        Toast.makeText( getApplicationContext( ), "Dialog finished!", Toast.LENGTH_SHORT ).show( );
    }
}

I have used this exact same design for a Yes/No dialog and it has worked great and I love it. I can easily call it from any activity with just two lines of code and show a Yes/No dialog with a customized title. Then the onClick callback contains which button was pressed so I have all the info I need from the dialog.

However, for this EditText dialog, I can't figure out how to get the data out of the EditText box inside the OnClick method. The only thing passed back is the button pressed and a DialogInterface reference (which as far as I can tell, doesn't help me get to the EditText data).

The only solutions I have seen involve embedding the OnClickListener code inside the builder code like this:

    builder.setItems(terms, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            Toast.makeText( getApplicationContext( ), inputView.getText().toString(), Toast.LENGTH_SHORT ).show( );
        }
    });

but that defeats the whole purpose of creating a generic dialog class that can be used from any Activity that needs an EditBox. Am I missing something obvious? Is this impossible?

2 Answers2

5

This is a very common question and actually has a really easy solution. You just need to use the new Dialog as the view to grab the control from.

Something like this..

EditText editTextFromDialog = (EditText)dialog.findViewById(the_editText_ID);

Then in you the onclick handler, as long as you are in scope for the declared control (if not you will have to modify the scope to suit your needs you can just grab the content.

String dialogInput = editTextFromDialog.getText().toString();
Quintin Robinson
  • 81,193
  • 14
  • 123
  • 132
  • 4
    Just to be explicit, though, for anyone reading this, dialog needs to be cast to a Dialog object before calling findViewById. dialog comes in as a DialogInterface reference, for which findViewById is undefined. – Clarence Simpson Aug 15 '11 at 16:42
  • @Clarence Simpson Good clarification! – Quintin Robinson Aug 15 '11 at 16:43
  • @ClarenceSimpson It should be something like `EditText editTextFromDialog = (EditText)dialog.getDialog().findViewById(the_editText_ID);` No "Dialog" cast. Just "EditText". – Danny Feb 10 '13 at 22:35
0

Excellent,

I implemented the onclick method in the activity and it works:

public class MainActivity extends FragmentActivity implements OnClickListener {

  protected void button1ActionPerformed() {
        // TODO Auto-generated method stub
        newFragment = new InputDialogFragment().newInstance( R.string.send_trasnsactions, R.string.dialog_fire_missiles, R.string.dialog_fire_missiles );
        newFragment.show(getSupportFragmentManager(), "missiles");

    }

 @Override
    public void onClick( DialogInterface dialog, int whichButton ) {
        Dialog x = (Dialog)dialog;
        EditText editTextFromDialog = (EditText)x.findViewById(2000);
        if ( whichButton == DialogInterface.BUTTON_POSITIVE ) {
            Log.i("x:"+editTextFromDialog.getText().toString(), "Ok");
        }else{
            Log.i("x", "cancel");
        }
    } 

}
Apurv
  • 3,723
  • 3
  • 30
  • 51