对话框片段:使用自定义布局的AlertDialog

24

我正在使用 Fragments API 重写我的应用程序。在原始应用程序中,我有一个类似以下代码创建的 AlertDialog

    LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View view = inflater.inflate(R.layout.button_dialog, null);
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setView(view);
    ListView mListView = (ListView) view.findViewById(R.id.mblist);
    builder.setTitle(getString(R.string.sysinfo)).setNeutralButton(
            getString(R.string.okay), null);
    Cursor dcursor = propManager.propCursor();
    if (dcursor.moveToFirst()) {
        startManagingCursor(dcursor);
        String[] from = { Constants.NAME_DET,
                Constants.VALUE_DET };
        int[] to = { R.id.mbname, R.id.mbvalue };
        SimpleCursorAdapter dadapter = new SimpleCursorAdapter(this,
                R.layout.info_list_row, dcursor, from, to);
        mListView.setAdapter(dadapter);
    }
    final Dialog dialog = builder.create();
    dialog.show();

我该如何使用DialogFragment显示相同的对话框?我已经阅读了文档,但不知道该如何继续。

我应该怎么做?

2个回答

50

我很惊讶没有人回答。这是解决方案:

public class PropDialogFragment extends DialogFragment {

    private PropDialogFragment() { /*empty*/ } 

    /** creates a new instance of PropDialogFragment */
    public static PropDialogFragment newInstance() {
        return new PropDialogFragment();
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        //getting proper access to LayoutInflater is the trick. getLayoutInflater is a                   //Function
        LayoutInflater inflater = getActivity().getLayoutInflater();

        View view = inflater.inflate(R.layout.my_dialog, null);
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setView(view);
        builder.setTitle(getActivity().getString(R.string.sysinfo)).setNeutralButton(
                getActivity().getString(R.string.okay), null);
        return builder.create();
    }
}

您可以使用以下方式显示对话框:

private void showDialog() {
    // DialogFragment.show() will take care of adding the fragment
    // in a transaction.  We also want to remove any currently showing
    // dialog, so make our own transaction and take care of that here.
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
    if (prev != null) {
        ft.remove(prev);
    }
    ft.addToBackStack(null);

    // Create and show the dialog.
    DialogFragment newFragment = PropDialogFragment.newInstance();
    newFragment.show(ft, "dialog");
}

1
你更愿意使用getActivity().getLayoutInflater()而不是调用系统服务并进行强制转换吗? - Anthony Chuinard
非常棒的答案。以防有人好奇,文档中已经涵盖了此内容 - Bob Liberatore
我曾认为必须使用“片段事务”才能显示“AlertDialog”。但现在我直接从“DialogFragment”使用“dialog.show();”,它也可以正常工作。 - JCarlosR
我知道这很老,但是片段不能有私有默认构造函数,因为它们可以被系统重新创建。 - Lukasz
LayoutInflater.from(getContext())似乎也可以代替getActivity().getLayoutInflater()。在片段中调用getActivity()总是让我感到紧张! - swanson

1
基本上,您可以像这样显示您的Fragment:
SherlockDialogFragment newFragment = new TimePickerFragment();
newFragment.show(getActivity().getSupportFragmentManager(), "timePicker");

这将是一个简单的TimePickerFragment(时间选择器片段):

public class TimePickerFragment extends SherlockDialogFragment implements TimePickerDialog.OnTimeSetListener{

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {

        final Calendar c = Calendar.getInstance();
        int hour = c.get(Calendar.HOUR_OF_DAY);
        int minute = c.get(Calendar.MINUTE);


        return new TimePickerDialog(getActivity(), this, hour, minute, DateFormat.is24HourFormat(getActivity()));
}
}

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