Get value from DialogFragment [duplicate]
Asked Answered
N

2

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();       
    }
}
Norword answered 27/9, 2012 at 13:38 Comment(1)
you would like to pass the typed value to your activity ?Lobule
L
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.
    }
}
Lobule answered 27/9, 2012 at 14:27 Comment(14)
@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?Mclellan
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...Lobule
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.Plectognath
@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.Lobule
bro I con't able to get the text from DialogFragment and setText in the MainActivity using your code.Miskolc
Bro I ask question based on your Answer Please see this linkMiskolc
@Miskolc this solution is working fine... what is your issue? from the answer i cannot see any setText or getText!!!Lobule
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 BlessMiskolc
@Miskolc On android we never instantiate Activity, so never never had seen new MainActivity() !!! sorry i do not provide custom support. Thank you.Lobule
I posted an answer here: #28620526Segalman
@AnisBENNSIR: wouldn't casting activity (MainActivity) getActivity() lead to potential memory leaksMauri
@KevinCrain if you don't keep a reference to your MainActivity on the Dialog, this will not lead to a memory leak...Lobule
@ AnisBENNSIR: could u please send a reference link to what you are saying so I may read further thanks!Mauri
@AnisBENNSIR : This helps me a lot +1Logjam
P
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.

Plascencia answered 6/8, 2013 at 13:51 Comment(2)
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...Goebbels
Yes, this is true, can anyone provide an example of a DialogFragment with a callback to the main activity?Mintun

© 2022 - 2024 — McMap. All rights reserved.