22

I want the DialogFragment to return a value to me that was entered in editQuantity when dismissed.

But i am not getting any way to make it work. I can do this by passing the value through the intent but that destroys the progress of the current activity.

Is there any way other than passing through intent that will return me value?

package com.example.myprojectname;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.text.InputType;
import android.util.Log;
import android.widget.EditText;

public class QuantityDialogFragment extends DialogFragment implements OnClickListener { 


    private EditText editQuantity;

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        editQuantity = new EditText(getActivity());
        editQuantity.setInputType(InputType.TYPE_CLASS_NUMBER);

        return new AlertDialog.Builder(getActivity())
        .setTitle(R.string.app_name)
        .setMessage("Please Enter Quantity")
        .setPositiveButton("OK", this)
        .setNegativeButton("CANCEL", null)
        .setView(editQuantity)
        .create();

    }

    @Override
    public void onClick(DialogInterface dialog, int position) {
        String value = editQuantity.getText().toString();
        Log.d("Quantity: ", value);
        dialog.dismiss();       
    }
}
Shrikant Ballal
  • 7,067
  • 7
  • 41
  • 61
Homam
  • 5,018
  • 4
  • 36
  • 39

2 Answers2

50

Assuming that you want to foward result to the calling Activity:) try this code snippet:

public class QuantityDialogFragment extends DialogFragment implements OnClickListener {

    private EditText editQuantity;

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        editQuantity = new EditText(getActivity());
        editQuantity.setInputType(InputType.TYPE_CLASS_NUMBER);

        return new AlertDialog.Builder(getActivity()).setTitle(R.string.app_name).setMessage("Please Enter Quantity")
                .setPositiveButton("OK", this).setNegativeButton("CANCEL", null).setView(editQuantity).create();

    }

    @Override
    public void onClick(DialogInterface dialog, int position) {
        String value = editQuantity.getText().toString();
        Log.d("Quantity: ", value);
        MainActivity callingActivity = (MainActivity) getActivity();
        callingActivity.onUserSelectValue(value);
        dialog.dismiss();
    }
}

and on Your activity add :

public class MainActivity extends FragmentActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        QuantityDialogFragment dialog = new QuantityDialogFragment();
        dialog.show(getSupportFragmentManager(), "Dialog");
    }

    /**
     * callback method from QuantityDialogFragment, returning the value of user
     * input.
     * 
     * @param selectedValue
     */
    public void onUserSelectValue(String selectedValue) {
        // TODO add your implementation.
    }
}
caballerog
  • 2,679
  • 1
  • 19
  • 32
Anis BEN NSIR
  • 2,555
  • 20
  • 29
  • @Anis But this requires the activity to implement a function with a particular name. Is there no mechanism to "return" the value, rather than call a function in the parent activity and pass it the value? – David Doria Sep 04 '13 at 20:17
  • 1
    This is just an example, it will depend if you need the activity response sync/async, for async you can use Local Broascast receiver. For sync implementation i think that this is the best one. This can be optimized with a common interface... – Anis BEN NSIR Sep 05 '13 at 11:17
  • 1
    I've not had too much success with casting the result from `getActivity()` to the appropriate activity. What if I want to reuse the dialog for multiple activities... I'll save myself a ClassCastException and implement the simple `setListener(interface name)` method in the dialog. – Someone Somewhere Oct 21 '13 at 22:31
  • 1
    @SomeoneSomewhere yes you can add Listener, as mentioned on my previous comments. You have to insure removing Listener, set it to null on the Dialog class, to avoid memory leaks due to circular references. – Anis BEN NSIR Oct 23 '13 at 10:56
  • bro I con't able to get the text from `DialogFragment` and `setText` in the `MainActivity` using your code. – reegan29 Jun 11 '15 at 09:44
  • Bro I ask question based on your Answer Please see this [link](http://stackoverflow.com/questions/30777753/how-to-get-the-data-from-dialogfragment-to-mainactivity-in-android/30778356?noredirect=1#comment49606974_30778356) – reegan29 Jun 11 '15 at 10:43
  • 1
    @reegan29 this solution is working fine... what is your issue? from the answer i cannot see any setText or getText!!! – Anis BEN NSIR Jun 11 '15 at 11:52
  • thanks for your reply bro ..Now I got solution .Sorry this is my mistake.I mistake this line `MainActivity mainActivity = new MainActivity();`.So I got error. now I change to `MainActivity callingActivity = (MainActivity) getActivity();`.God Bless – reegan29 Jun 11 '15 at 13:42
  • 1
    @reegan29 On android we never instantiate Activity, so never never had seen new MainActivity() !!! sorry i do not provide custom support. Thank you. – Anis BEN NSIR Jun 11 '15 at 13:48
  • I posted an answer here: http://stackoverflow.com/questions/28620026/implement-dialogfragment-interface-in-onclicklistener/33713825#33713825 – user2288580 Nov 14 '15 at 21:56
  • @AnisBENNSIR: wouldn't casting activity `(MainActivity) getActivity()` lead to potential memory leaks – Kevin Crain Dec 08 '15 at 20:22
  • @KevinCrain if you don't keep a reference to your MainActivity on the Dialog, this will not lead to a memory leak... – Anis BEN NSIR Dec 10 '15 at 11:02
  • @ AnisBENNSIR: could u please send a reference link to what you are saying so I may read further thanks! – Kevin Crain Dec 15 '15 at 12:29
  • @AnisBENNSIR : This helps me a lot +1 – Terance Wijesuriya Dec 20 '16 at 09:53
4

Taking this idea a little further, I created a listener interface inside the dialog and implemented it in the main activity.

public interface OnDialogResultListener {
    public abstract void onPositiveResult(String value);
    public abstract void onNegativeResult();
}

public void setOnDialogResultListener(OnDialogResultListener listener) {
    this.onDialogResultListener = listener;
}

Call onNegativeResult() inside an overriden onCancel(DialogInterface) and onPositiveResult(String) where you want your dialog to return the value.

Note: don't forget to dismiss() your dialog after calling onPositiveResult() or the dialog window will stay opened.

Then inside your main activity you can create a listener for the dialog, like so:

QuantityDialogFragment dialog = new QuantityDialogFragment();
dialog.setOnDialogResultListener(new QuantityDialogFragment.OnDialogResultListener() {
        @Override
        public void onPositiveResult(String value) {
            //Do something...
        }

        @Override
        public void onNegativeResult() {
            //Do something...
        }
    });

This will make your dialog easier to reuse later.

mrolcsi
  • 49
  • 3
  • 9
    This won't always work - if the screen is rotated the activity will be re-created and the dialog fragment will be re-created. But they will no longer be connected b/c the "show dialog" code was not re-executed to set up the listener... – Scott Stanchfield Aug 09 '13 at 14:53
  • Yes, this is true, can anyone provide an example of a DialogFragment with a callback to the main activity? – mparkes May 09 '16 at 21:54