从片段显示对话框?

Zso*_*agy 114 android android-dialog android-dialogfragment

我有一些需要显示常规对话框的片段.在这些对话框中,用户可以选择是/否答案,然后片段应该相应地运行.

现在,Fragment该类没有onCreateDialog()覆盖的方法,所以我想我必须在包含的外部实现对话框Activity.没关系,但是Activity需要以某种方式向片段报告所选择的答案.我当然可以在这里使用回调模式,因此片段在Activity一个监听器类中注册自己,而Activity会通过它报告回答,或类似的东西.

但对于一个简单的任务来说,这似乎是一个相当大的混乱,因为在一个片段中显示一个"简单的"是 - 否对话框.而且,这样我的Fragment自足也会减少.

有没有更清洁的方法来做到这一点?

编辑:

这个问题的答案并没有真正详细解释如何使用DialogFragments来显示Fragments中的对话框.所以AFAIK,走的路是:

  1. 显示片段.
  2. 需要时,实例化DialogFragment.
  3. 将原始Fragment设置为此DialogFragment的目标,使用.setTargetFragment().
  4. 使用原始片段中的.show()显示DialogFragment.
  5. 当用户在此DialogFragment上选择一些选项时,通知原始片段有关此选择(例如,用户单击"是"),您可以使用.getTarget()获取原始片段的引用.
  6. 关闭DialogFragment.

mgv*_*mgv 37

您应该使用DialogFragment.

  • ListFragment子类将通过实例化新的子类来使用DialogFragments,而不是通过子类化DialogFragment.(DialogFragment是一个实现为片段的对话框,而不是可以显示对话框的片段.) (16认同)
  • 不幸的是,这种方法比以前的Android版本的经典托管对话框方法更冗长,但它现在是首选方法.您可以通过使用`FragmentManager`的`putFragment`和`getFragment`方法完全避免引用`Activity`,允许`DialogFragment`直接向调用片段报告(即使在方向更改后). (8认同)
  • 请添加一些代码段,以便我们轻松理解 (2认同)

Mar*_*k D 31

我必须谨慎怀疑之前接受的答案,即使用DialogFragment是最佳选择.DialogFragment的预期(主要)目的似乎是显示对话框本身的片段,不是显示具有要显示的对话框的片段.

我相信使用片段的活动在对话框和片段之间进行调解是更好的选择.

  • 由于托管对话框(`onCreateDialog`)方法很快就会被弃用,我不同意并说"DialogFragment"确实是要走的路. (10认同)
  • 接受的答案意味着使用DialogFragment而不是Dialog,而不是使用ListFragment,AFAICS. (4认同)

War*_*zit 24

以下是是/否DialogFragment的完整示例:

班级:

public class SomeDialog extends DialogFragment {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        return new AlertDialog.Builder(getActivity())
            .setTitle("Title")
            .setMessage("Sure you wanna do this!")
            .setNegativeButton(android.R.string.no, new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    // do nothing (will close dialog)
                }
            })
            .setPositiveButton(android.R.string.yes,  new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    // do something
                }
            })
            .create();
    }
}
Run Code Online (Sandbox Code Playgroud)

要开始对话:

        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        // Create and show the dialog.
        SomeDialog newFragment = new SomeDialog ();
        newFragment.show(ft, "dialog");
Run Code Online (Sandbox Code Playgroud)

您还可以让该类实现onClickListener并使用它而不是嵌入式侦听器.

回调活动

如果你想实现回调,这就是你的活动:

YourActivity extends Activity implements OnFragmentClickListener
Run Code Online (Sandbox Code Playgroud)

@Override
public void onFragmentClick(int action, Object object) {
    switch(action) {
        case SOME_ACTION:
        //Do your action here
        break;
    }
}
Run Code Online (Sandbox Code Playgroud)

回调类:

public interface OnFragmentClickListener {
    public void onFragmentClick(int action, Object object);
}
Run Code Online (Sandbox Code Playgroud)

然后,要从片段执行回调,您需要确保侦听器附加如下:

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    try {
        mListener = (OnFragmentClickListener) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString() + " must implement listeners!");
    }
}
Run Code Online (Sandbox Code Playgroud)

并且执行回调如下:

mListener.onFragmentClick(SOME_ACTION, null); // null or some important object as second parameter.
Run Code Online (Sandbox Code Playgroud)

  • 这并不能解释如何从片段中启动它 (3认同)

Epi*_*rce 12

对我来说,是以下 -

MyFragment:

public class MyFragment extends Fragment implements MyDialog.Callback
{
    ShowDialog activity_showDialog;

    @Override
    public void onAttach(Activity activity)
    {
        super.onAttach(activity);
        try
        {
            activity_showDialog = (ShowDialog)activity;
        }
        catch(ClassCastException e)
        {
            Log.e(this.getClass().getSimpleName(), "ShowDialog interface needs to be     implemented by Activity.", e);
            throw e;
        }
    }

    @Override
    public void onClick(View view) 
    {
        ...
        MyDialog dialog = new MyDialog();
        dialog.setTargetFragment(this, 1); //request code
        activity_showDialog.showDialog(dialog);
        ...
    }

    @Override
    public void accept()
    {
        //accept
    }

    @Override
    public void decline()
    {
        //decline
    }

    @Override
    public void cancel()
    {
        //cancel
    }

}
Run Code Online (Sandbox Code Playgroud)

MyDialog:

public class MyDialog extends DialogFragment implements View.OnClickListener
{
    private EditText mEditText;
    private Button acceptButton;
    private Button rejectButton;
    private Button cancelButton;

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

    public MyDialog()
    {
        // Empty constructor required for DialogFragment
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View view = inflater.inflate(R.layout.dialogfragment, container);
        acceptButton = (Button) view.findViewById(R.id.dialogfragment_acceptbtn);
        rejectButton = (Button) view.findViewById(R.id.dialogfragment_rejectbtn);
        cancelButton = (Button) view.findViewById(R.id.dialogfragment_cancelbtn);
        acceptButton.setOnClickListener(this);
        rejectButton.setOnClickListener(this);
        cancelButton.setOnClickListener(this);
        getDialog().setTitle(R.string.dialog_title);
        return view;
    }

    @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 (v == rejectButton)
            {
                callback.decline();
                this.dismiss();
            }
            else if (v == cancelButton)
            {
                callback.cancel();
                this.dismiss();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

活动:

public class MyActivity extends ActionBarActivity implements ShowDialog
{
    ..

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

DialogFragment布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/dialogfragment_textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="10dp"
        android:text="@string/example"/>

    <Button
        android:id="@+id/dialogfragment_acceptbtn"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:layout_centerHorizontal="true"
        android:layout_below="@+id/dialogfragment_textview"
        android:text="@string/accept"
        />

    <Button
        android:id="@+id/dialogfragment_rejectbtn"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_alignLeft="@+id/dialogfragment_acceptbtn"
        android:layout_below="@+id/dialogfragment_acceptbtn"
        android:text="@string/decline" />

     <Button
        android:id="@+id/dialogfragment_cancelbtn"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="20dp"
        android:layout_alignLeft="@+id/dialogfragment_rejectbtn"
        android:layout_below="@+id/dialogfragment_rejectbtn"
        android:text="@string/cancel" />

     <Button
        android:id="@+id/dialogfragment_heightfixhiddenbtn"
        android:layout_width="200dp"
        android:layout_height="20dp"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="20dp"
        android:layout_alignLeft="@+id/dialogfragment_cancelbtn"
        android:layout_below="@+id/dialogfragment_cancelbtn"
        android:background="@android:color/transparent"
        android:enabled="false"
        android:text=" " />
</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)

正如名字dialogfragment_heightfixhiddenbtn所示,我无法找到一种方法来解决底部按钮的高度被切成两半尽管说wrap_content,所以我添加了一个隐藏的按钮被"切"成两半而不是.对不起黑客.