给DialogFragment的对话框添加积极/消极按钮

46

我已经编写了一个DialogFragment。现在我意识到我想要它像AlertDialog一样有一个积极的和一个消极的按钮。在保持我已经编写的代码的情况下,我该如何实现这样的功能?

public class DoublePlayerChooser extends DialogFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);        

    setStyle(DialogFragment.STYLE_NORMAL,0);



}

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {

    return new AlertDialog.Builder(getActivity())
            .setTitle("title")
            .setPositiveButton("OK",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                        // do something...
                    }
                }
            )
            .setNegativeButton("Cancel",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                        dialog.dismiss();
                    }
                }
            )
            .create();
}



@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View v = inflater.inflate(R.layout.doubleplayerchooser, container, false);
    getDialog().setTitle("Enter Players");

    firstPlayerPicker =  (ImageButton) v.findViewById(R.id.imageButton1);
    firstPlayerPicker.setOnClickListener(new OnClickListener() {
        public void onClick(final View v){

            callContactPicker(1);

        }       
    });

    secondPlayerPicker =  (ImageButton) v.findViewById(R.id.ImageButton01);
    secondPlayerPicker.setOnClickListener(new OnClickListener() {
        public void onClick(final View v){

            callContactPicker(2);

        }       
    });

    loadFromFile =  (ImageButton) v.findViewById(R.id.imageButton2);
    loadFromFile.setOnClickListener(new OnClickListener() {
        public void onClick(final View v){



        }       
    });

    firstTextfield =  (EditText) v.findViewById(R.id.editText1);
    secondTextfield =  (EditText) v.findViewById(R.id.EditText01);

    firstImage = (ImageView) v.findViewById(R.id.imageView1);
    secondImage = (ImageView) v.findViewById(R.id.ImageView01);



    return v;
}
5个回答

71

这就是我找到答案的方法。我删除了onCreateView并修改了onCreateDialog。 实际上,这个链接 提供了答案,因此所有的功劳都应归于那里。我只是为了万一有人先看到这个问题才发的。

    @Override
public Dialog onCreateDialog(Bundle savedInstanceState) {

    AlertDialog.Builder b=  new  AlertDialog.Builder(getActivity())
    .setTitle("Enter Players")
    .setPositiveButton("OK",
        new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                // do something...
            }
        }
    )
    .setNegativeButton("Cancel",
        new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                dialog.dismiss();
            }
        }
    );

    LayoutInflater i = getActivity().getLayoutInflater();

    View v = i.inflate(R.layout.doubleplayerchooser,null);

    firstPlayerPicker =  (ImageButton) v.findViewById(R.id.imageButton1);
    firstPlayerPicker.setOnClickListener(new OnClickListener() {
        public void onClick(final View v){

            callContactPicker(1);

        }       
    });

    secondPlayerPicker =  (ImageButton) v.findViewById(R.id.ImageButton01);
    secondPlayerPicker.setOnClickListener(new OnClickListener() {
        public void onClick(final View v){

            callContactPicker(2);

        }       
    });

    loadFromFile =  (ImageButton) v.findViewById(R.id.imageButton2);
    loadFromFile.setOnClickListener(new OnClickListener() {
        public void onClick(final View v){



        }       
    });

    firstTextfield =  (EditText) v.findViewById(R.id.editText1);
    secondTextfield =  (EditText) v.findViewById(R.id.EditText01);

    firstImage = (ImageView) v.findViewById(R.id.imageView1);
    secondImage = (ImageView) v.findViewById(R.id.ImageView01);


    b.setView(v);
    return b.create();
}

1
如果在onCreateView(LayoutInflater.from(getActivity()),null,savedInstance)中创建内容视图,会更清晰明了。 - Meow Cat 2012

7

您需要重写DialogFragments的onCreateDialog(...)方法:

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {

    return new AlertDialog.Builder(getActivity())
            .setTitle("title")
            .setPositiveButton("OK",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                        // do something...
                    }
                }
            )
            .setNegativeButton("Cancel",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                        dialog.dismiss();
                    }
                }
            )
            .create();
}

这是从这里获取的:Android: disable DialogFragment OK/Cancel buttons

根据您收到的错误消息(“必须调用请求功能…”),我建议:

不要在Activity或其他地方调用requestFeature()之前调用setContentView()

此外:

不要在onCreate()内部调用setStyle(...)

请在创建Fragment时进行调用。

YourDialogFragment f = new YourDialogFragment(Context);
f.setStyle(...);
// and so on ...

2
我已经这样做了,但是我收到了一个异常请求,要求在添加内容之前调用功能。Android - Libathos
那么请发一些你的代码,看看我的更新答案。 - Philipp Jahoda
当我删除了onCreateView方法后,程序运行时没有出现错误。如果这对你有帮助的话。 - Libathos
onCreateView已经发布。setStyle不是我的,它是为API而设的。我已经删除了setStyle,但它没有起作用。 - Libathos
哈哈,我太蠢了,没往下滚动 :) - 无论如何,我认为你的错误与 setStyle(...) 相关,请查看我的更新答案。 - Philipp Jahoda
显示剩余3条评论

4
最清晰的方式。
// Your own onCreate_Dialog_View method
public View onCreateDialogView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    return inflater.inflate(R.layout.your_layout, container); // inflate here
}

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    // do something with 'view'
}

@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    // setup dialog: buttons, title etc
    AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(getActivity())
            .setTitle(R.string.dialog_fragment_author_title)
            .setNegativeButton(R.string.dialog_fragment_author_close,
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int whichButton) {
                            dialog.dismiss();
                        }
                    }
            );

    // call default fragment methods and set view for dialog
    View view = onCreateDialogView(getActivity().getLayoutInflater(), null, null);
    onViewCreated(view, null);
    dialogBuilder.setView(view);

    return dialogBuilder.create();
}

1
这段内容有点陈旧,但最近我一直在扩展AppCompatDialogFragment时覆盖onCreateView。只需将自己的按钮放入您在onCreateView中返回的相同布局中 - 使用像@style/Widget.AppCompat.Button.Borderless这样的样式。
您还可以获得额外的奖励,即控制对话框在单击操作按钮时自动解除,特别是因为这些自定义视图有时需要必需的输入,并且您希望阻止单击按钮时对话框的自动关闭。
onCreateDialog中使用自定义视图始终感觉很糟糕,因为您没有容器来填充它。Google尝试通过新的v7 AlertDialog.Builder方法setView(int layoutResId)使API更加友好,但此时您无法调用findViewById
您应该在styles.xml中添加类似于以下的主题:
<style name="AlertDialog" parent="Theme.AppCompat.Light.Dialog.Alert">
    <item name="colorPrimary">@color/material_light_blue_500</item>
    <item name="colorPrimaryDark">@color/material_light_blue_800</item>
    <item name="colorAccent">@color/material_light_blue_a400</item>
    <item name="colorButtonNormal">@color/material_light_blue_500</item>
    <item name="colorControlNormal">@color/material_light_blue_600</item>
    <item name="colorControlActivated">@color/material_light_blue_a100</item>
    <item name="colorControlHighlight">@color/material_light_blue_a100</item>
</style>

您必须在DialogFragment中覆盖onCreateDialog方法,并返回new AppCompatDialog(getActivity(), R.style.AlertDialog)


1
要添加操作按钮,请调用setPositiveButton()setNegativeButton()方法:
public class FireMissilesDialogFragment extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    // Use the Builder class for convenient dialog construction
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    builder.setMessage(R.string.dialog_fire_missiles)
           .setPositiveButton(R.string.fire, new DialogInterface.OnClickListener() {
               public void onClick(DialogInterface dialog, int id) {
                   // FIRE ZE MISSILES!
               }
           })
           .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
               public void onClick(DialogInterface dialog, int id) {
                   // User cancelled the dialog
               }
           });
    // Create the AlertDialog object and return it
    return builder.create();
}
}

关于DialogFragment的更多信息在这里


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