24

I do have a FragmentActivity which contains a Fragment list (with methods to navigate between them). In one of those fragments I need to call a DialogFragment to display a "zoom" on a Picture contained in that fragment.

But it seems that you can't call a DialogFragment directly from a Fragment.

Is there any way to get some kind of "callback" to the FragmentActivity to make this display the DialogFragment over the fragment.

Or simply a "glitch" to call it directly from the Fragment.

If that is the case what are my options?

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
Elie Page
  • 243
  • 1
  • 2
  • 5

8 Answers8

21

When you create a new Dialog, you can simply call it using this (very) simple method from a Fragment.

DialogFragment dialog = DialogFragment.instantiate(getActivity(), "Hello world");
dialog.show(getFragmentManager(), "dialog");

If you want to use your own dialog, please use that kind of code.

public class MyDialogFragment extends DialogFragment
{
    //private View pic;

    public MyDialogFragment()
    {
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState)
    {
        View view = getActivity().getLayoutInflater().inflate(R.layout.fragment_my_dialog, new LinearLayout(getActivity()), false);

        // Retrieve layout elements
        TextView title = (TextView) view.findViewById(R.id.text_title);

        // Set values
        title.setText("Not perfect yet");

        // Build dialog
        Dialog builder = new Dialog(getActivity());
        builder.requestWindowFeature(Window.FEATURE_NO_TITLE);
        builder.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
        builder.setContentView(view);
        return builder;
    }
}
Manitoba
  • 8,522
  • 11
  • 60
  • 122
  • 2
    Seems to work for DialogFragment. But when i create : public class MyDialogFragment extends DialogFragment {} With a "oncreateView" inside (calling a xml) It breaks and display me this message : "canot resolve method show" But since MyDialogFrament extends DIalogFragments without any override, shouldn't this work in each case ? – Elie Page Sep 17 '14 at 10:05
  • 2
    I've updated my answer with a sample based on your dialog request. – Manitoba Sep 17 '14 at 10:08
  • Thanks, helped me a lot both resolving my problems and understanding how theses fragments work. – Elie Page Sep 17 '14 at 10:13
  • 1
    Once you'll correctly understand every fragment subtility, you won't user `Activity` anymore ;) – Manitoba Sep 17 '14 at 10:14
  • What happens on rotation? – EpicPandaForce Sep 17 '14 at 10:24
  • Please describe your question. – Manitoba Sep 17 '14 at 10:25
  • it seems that it still breaks on the dFragment.show(getFragmentManager(), "dialog"); saying "cannot resolve method show" when i use my own dialogFragment (with a single override public Dialog onCreateDialog as u just did in example. – Elie Page Sep 17 '14 at 13:42
  • 2
    but if ever I use the basic DialogFragment instead it suddenly can resolve the method "show". Since MyDialogFragment extends DialogFragment and only overrides onCreateDialog, it seems that method show must be linked in some part with the onCreate ? else i don't understand why it doesn't work in one case and it works in the other since there should be no difference between both. – Elie Page Sep 17 '14 at 15:00
  • @EliePage you can use getActivity().getFragmentManager() – Charu Jun 27 '16 at 06:40
  • Where is the show method in dialog fragment? Its asking me to create one. :( – Alok Rajasukumaran Jun 29 '16 at 06:48
  • 1
    `insantiate(Context, String)` is deprecated in Java – wbk727 Feb 11 '19 at 18:58
8

it will help if you need to show a fragment dialog inside a fragment

DialogFragment

public class DialogBoxFragment extends DialogFragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
        View rootView = inflater.inflate(R.layout.dialog_fragment, container, false);
        getDialog().setTitle("simple dialog");
        return rootView;
    }
}

Now showing the fragment dialog into a fragment

DialogFragment dialogFragment = new DialogFragment ();
                            dialogFragment.show(getActivity().getFragmentManager(),"simple dialog");
Sufian
  • 6,405
  • 16
  • 66
  • 120
PradeepNama
  • 511
  • 6
  • 6
7

Check for import statements. If we use

ExampleDialogFragment dialog = new ExampleDialogFragment ();
dialog .show(getFragmentManager(), "example");

Then make sure to import

import android.app.DialogFragment;
import android.app.Fragment;

not from the support library.

import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
Amit
  • 3,422
  • 3
  • 28
  • 39
1

For me, it was the following: https://stackoverflow.com/a/25056160/2413303

The most important parts are that you need to have a Callback for your dialog fragment:

public class MyFragment extends Fragment implements MyDialog.Callback

Which kinda works like this

public class MyDialog extends DialogFragment implements View.OnClickListener {

public static interface Callback
{
    public void accept();
    public void decline();
    public void cancel();
}

You make the Activity show the dialog for you from the Fragment:

    MyDialog dialog = new MyDialog();
    dialog.setTargetFragment(this, 1); //request code
    activity_showDialog.showDialog(dialog);

Where showDialog() for me was the following method:

@Override
public void showDialog(DialogFragment dialogFragment)
{
    FragmentManager fragmentManager = getSupportFragmentManager();
    dialogFragment.show(fragmentManager, "dialog");
}

And you call back onto your target fragment:

@Override
public void onClick(View v)
{
    Callback callback = null;
    try
    {
        callback = (Callback) getTargetFragment();
    }
    catch (ClassCastException e)
    {
        Log.e(this.getClass().getSimpleName(), "Callback of this class must be implemented by target fragment!", e);
        throw e;
    }

    if (callback != null)
    {
        if (v == acceptButton)
        {   
            callback.accept();
            this.dismiss();
        }
        else if (...) {...}
    }
    else
    {
        Log.e(this.getClass().getSimpleName(), "Callback was null.");
    }
}
Community
  • 1
  • 1
EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428
  • I was using `onCreateView()` instead of `onCreateDialog()` in my `DialogFragment`. – EpicPandaForce Sep 17 '14 at 10:15
  • 1
    When on public void showDialog(DialogFragment dialogFragment) { FragmentManager fragmentManager = getSupportFragmentManager(); dialogFragment.show(fragmentManager, "dialog"); } he can't resolve the method "getSupportFragmentManager(); – Elie Page Sep 17 '14 at 13:41
  • that's in `FragmentActivity`, you call it through an interface that's attached into the `Fragment` in `onAttach()`. See the linked answer because that's more in-depth, I just didn't want to repeat **everything** twice and just copy paste, I left only the important elements here. – EpicPandaForce Sep 17 '14 at 14:11
1

Try this simple class I did in a myown project:

        public class UIDialogMessage extends DialogFragment {

    public static UIDialogMessage newInstance(int aTitleID, int aMessageID) {
        return newInstance(aTitleID, aMessageID, true);
    }

    public static UIDialogMessage newInstance(int aTitleID, int aMessageID, boolean aDoIt) {
        UIDialogMessage frag = new UIDialogMessage();
        Bundle args = new Bundle();
        args.putInt("titleID", aTitleID);
        args.putInt("messageID", aMessageID);
        args.putBoolean("keyBoolDoSomething", aDoIt);
        frag.setArguments(args);
        return frag;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        int mTitleID = getArguments().getInt("titleID");
        int mMessageID = getArguments().getInt("messageID");
        final boolean mDoIt= getArguments().getBoolean("keyBoolDoSomething", true);

        return new AlertDialog.Builder(getActivity())
                .setTitle(mTitleID)
                .setMessage(mMessageID)
                .setPositiveButton(getResources().getString(R.string.dialog_button_gotcha),
                        new DialogInterface.OnClickListener() {

                            public void onClick(DialogInterface dialog, int whichButton) {
                                dialog.dismiss();
                                if (mDoIt)
                                    doIt();
                            }
                        })
                .create();
    }

    private void doIt() {
        ...
    }
}

and you can call from a Fragment as shown below:

showDialog(R.string.dialog_title, R.string.dialog_message, false);

private void showDialog(int aTitleID, int aMessageID, boolean aDoIt) {
        DialogFragment uiDialogMessage = UIDialogMessage.newInstance(aTitleID, aMessageID, aDoIt);
        uiDialogMessage.show(getFragmentManager(), "dialog");
    }
Ciro Rizzo
  • 492
  • 4
  • 8
1

I had same issue solved by import

import android.support.v4.app.ListFragment;

instead of

import android.app.ListFragment;
Khalid
  • 11
  • 1
1

Your calling fragment

public class Order_Today extends Fragment {
    public void callDialogFragment() {
        DialogFragmentToOpen add = new DialogFragmentToOpen();
        add.show(getActivity().getSupportFragmentManager(),"dialog");
    }
}

Your dialog fragment

public class DialogFragmentToOpen extends DialogFragment {}
0
 ShowValueDialog().showNow(
                        this@OrderFragment.childFragmentManager,
                        "your string"
                    )

**or You Can use this**

this@OrderFragment.parentFragmentManager?.let { it1 -> ShowValueDialog().showNow(it1,"your string") }
eagerprince
  • 115
  • 1
  • 5