从Fragment(而非FragmentActivity)调用DialogFragment?

24

我有一个包含片段列表的FragmentActivity(具有在它们之间导航的方法)。

在这些片段中的一个中,我需要调用一个DialogFragment来显示该片段中包含的图片的“缩放”。

但似乎无法直接从Fragment调用DialogFragment。

是否有任何方法可以获得某种“回调”到FragmentActivity,以便使其在片段上显示DialogFragment?

或者只是通过Fragment直接调用它的某个“故障”。

如果是这样,我的选项有哪些?


@blackbelt 我不能这样做,因为他无法解析show方法。 - Elie Page
8个回答

21
当您创建一个新的Dialog时,您可以从Fragment中使用这个(非常)简单的方法来调用它。
DialogFragment dialog = DialogFragment.instantiate(getActivity(), "Hello world");
dialog.show(getFragmentManager(), "dialog");

如果你想使用自己的对话框,请使用那种代码。

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;
    }
}

2
似乎对于DialogFragment有效。 但是当我创建:public class MyDialogFragment extends DialogFragment {}里面有一个“oncreateView”(调用xml) 它会中断并显示这个消息: “无法解决方法show” 但是由于MyDialogFrament扩展了没有任何覆盖的DIalogFragments,所以在每种情况下都应该起作用,不是吗? - Elie Page
2
我已根据您的对话请求更新了我的答案,并提供了一个示例。 - Manitoba
1
一旦您正确理解了每个片段的微妙之处,您将不再使用Activity ;) - Manitoba
2
但如果我使用基本的DialogFragment,它就能突然解决"show"方法。由于 MyDialogFragment 扩展了 DialogFragment 并且仅覆盖了 onCreateDialog 方法,因此似乎方法 show 必须与 onCreate 在某些部分链接?否则我不明白为什么在一种情况下它不起作用,在另一种情况下它可以工作,因为两者之间应该没有区别。 - Elie Page
1
在Java中,insantiate(Context, String)已被弃用。 - wbk727
显示剩余6条评论

8

如果您需要在片段内显示一个片段对话框,这将有所帮助。

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;
    }
}

现在将片段对话框显示为片段

DialogFragment dialogFragment = new DialogFragment ();
                            dialogFragment.show(getActivity().getFragmentManager(),"simple dialog");

4
从这个 DialogFragment 返回数据给调用它的 Fragment 怎么样? - EMalik

7

检查导入语句。 如果我们使用

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

然后确保导入。
import android.app.DialogFragment;
import android.app.Fragment;

不是来自支持库。

import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;

1

我遇到了同样的问题,通过导入解决了

import android.support.v4.app.ListFragment;

替代

import android.app.ListFragment;

1
对我而言,它是以下内容:https://dev59.com/MW435IYBdhLWcg3weQBy#25056160 最重要的部分是你需要为你的对话框片段设置一个Callback
public class MyFragment extends Fragment implements MyDialog.Callback

这有点像这样。
public class MyDialog extends DialogFragment implements View.OnClickListener {

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

你可以从Fragment中调用Activity的方法来展示对话框:
    MyDialog dialog = new MyDialog();
    dialog.setTargetFragment(this, 1); //request code
    activity_showDialog.showDialog(dialog);

对我而言,showDialog() 是以下方法:

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

然后您回调到目标片段:

@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.");
    }
}

жҲ‘еңЁжҲ‘зҡ„DialogFragmentдёӯдҪҝз”ЁдәҶonCreateView()иҖҢйқһonCreateDialog()гҖӮ - EpicPandaForce
1
当在以下代码中: public void showDialog(DialogFragment dialogFragment) { FragmentManager fragmentManager = getSupportFragmentManager(); dialogFragment.show(fragmentManager, "dialog"); } 无法解析方法“getSupportFragmentManager();”时,需要注意。 - Elie Page
FragmentActivity中,您可以通过在onAttach()中附加到Fragment的接口来调用它。请参见链接的答案,因为那里更详细,我只是不想重复所有内容并复制粘贴,所以我只留下了重要的元素。 - EpicPandaForce

1
尝试一下我在自己的项目中编写的这个简单类:
        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() {
        ...
    }
}

你可以像下面展示的那样从碎片中调用:

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");
    }

1

你的调用片段

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

你的对话片段
public class DialogFragmentToOpen extends DialogFragment {}

不错的尝试,但请加上一些解释,以便每个人都能轻松理解。 - Ajay Mistry

0
 ShowValueDialog().showNow(
                        this@OrderFragment.childFragmentManager,
                        "your string"
                    )

**or You Can use this**

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接