Android Multiple Nested DialogFragment



我有一个场景,我显示一个DialogFragment(使用getSupportFragmentManager()),显示一个值列表和一个"添加"按钮。如果用户单击添加按钮,我将显示另一个DialogFragment(使用由EditTextButton组成的getChildFragmentManager()。当用户单击新Button如果值通过验证时,我会将其添加到列表中。如果它没有通过验证,我会显示另一个显示错误消息的DialogFragment,以及一个"确定"按钮。我希望当按下"确定"按钮时,用户仍然会看到带有EditTextButtonDialogFragment,以便他们可以查看错误值并可能更改它。但是,当在错误消息DialogFragment中按下"确定"按钮时,对话框将关闭,并且仅显示原始DialogFragment(具有值列表的)。

第三个DialogFragment被关闭后,我将如何保持第二个仍然显示?

编辑:这里有一些代码片段:

//clicking this button shows the first ("outer") fragment
findViewById(R.id.voicemail_notifications_email_addresses).setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            AddressListDialog.newInstance( 
                   line, AddressListDialog.VOICEMAIL_NOTIFICATIONS_EMAIL)
                  .show(((FragmentActivity)getContext()).getSupportFragmentManager(), "dialog");
        }
});
public static class AddressListDialog extends DialogFragment {
    public AddressListDialog() {}
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        final View v = LayoutInflater.from(getActivity()).inflate(R.layout.vm_address_list_dialog, null);
        ListView lv = (ListView) v.findViewById(R.id.voicemail_notifications_address_list);
        final AddressAdapter adapter = new AddressAdapter();
        lv.setAdapter(adapter);
        v.findViewById(R.id.voicemail_add_address_button).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                //first child fragment
                AddAddressDialog.newInstance(getType()).setAdapter(adapter)
                                .show(getChildFragmentManager(), "dialog");
            }
        });
        Dialog d = new AlertDialog.Builder(getActivity())
                .setTitle(titleRes)
                .setView(v)
                .setPositiveButton(R.string.global_dialog_pos, new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int whichButton) {
                            dialog.dismiss();
                        }
                    }
                )
                .create();
        return d;
    }
    private class AddressAdapter extends BaseAdapter {
        .
        .
        .
        public boolean add(LineVoicemailInfo.VmContact contact) {
            if(addresses.size() >= 3) {
                return false;
            }
            else if(!contact.isValid(isEmailType())) {
                return true;
            }
            else {
                addresses.add(contact);
                notifyDataSetChanged();
                return true;
            }
        }
public static class AddAddressDialog extends DialogFragment {
    private AddressAdapter adapter;
    public AddAddressDialog() {}
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        DialogInterface.OnClickListener onPosClick = null;
        final View v;
        v = LayoutInflater.from(getActivity()).inflate(R.layout.voicemail_add_email_address, null);
        onPosClick = new DialogInterface.OnClickListener() {                        
            @Override
            public void onClick(DialogInterface dialog, int which) {
                LineVoicemailInfo.VmContact contact = new LineVoicemailInfo.VmContact(((EditText)v.findViewById(R.id.voicemail_add_email_address)).getText().toString());
                if(!adapter.add(contact)) {
                    //second child fragment
                    BadAddressDialog.newInstance("Not a valid address")
                                    .show(getChildFragmentManager(), "dialog");
                }
            }
        };

        Dialog d = new AlertDialog.Builder(getActivity())
                .setTitle("Add Address")
                .setView(v)
                .setCancelable(false)
                .setPositiveButton(R.string.voicemail_addresses_add, onPosClick)
                .setNegativeButton(R.string.global_dialog_neg, new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int whichButton) {
                           dialog.dismiss();
                        }
                })
                .create();
        setCancelable(false);
        return d;
    }
}
public static class BadAddressDialog extends DialogFragment {           
        public BadAddressDialog() {}
        public static BadAddressDialog newInstance(String message) {
            BadAddressDialog frag = new BadAddressDialog();
            Bundle args = new Bundle();
            args.putString("message", message);
            frag.setArguments(args);
            return frag;
        }
        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {   
            String message = getArguments().getString("message");
            Dialog d = new AlertDialog.Builder(getActivity())
                    .setTitle("Error adding address")
                    .setMessage(message)
                    .setCancelable(false)
                    .setPositiveButton(R.string.global_dialog_pos, new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int whichButton) {
                            dialog.dismiss();
                        }
                    })
                    .create();
            setCancelable(false);
            return d;
        }
    }

我想问题是您使用标准show方法来显示对话框。根据Android消息来源,此方法不会将片段添加到backstack,因此最上面的对话框被关闭,中间的对话框也被忽略。

在调用show之前,您应该自己开始传输,并将事务添加到backstack(调用addToBackStack)。对话片段文档页面上显示了一个示例。

最新更新