如何设置DialogFragment的标题?

166

这应该是一个简单的任务,但出于某种原因,我找不到设置DialogFragment标题的方法。(我正在使用onCreateView重载函数设置对话框内容。)

默认样式会留出标题的位置,但是我在DialogFragment类中找不到任何设置标题的方法。

当使用onCreateDialog方法设置内容时,标题会以某种神奇的方式自动设置,因此我想知道这是否是设计上的缺陷,或者在使用onCreateView重载函数时是否有特殊的技巧可以设置它。

7个回答

316
你可以使用 getDialog().setTitle("My Dialog Title") 来设置对话框的标题。就像这样:
public static class MyDialogFragment extends DialogFragment {
    ...
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // Set title for this dialog
        getDialog().setTitle("My Dialog Title");

        View v = inflater.inflate(R.layout.mydialog, container, false);
        // ...
        return v;
    }
    // ...
}

6
是的,确实getDialog().setTitle()就可以解决问题了。看完这个方法后,它确实很有道理,但由于某些原因,我本来期望设置标题的调用在DialogFragment类本身(与setStyle()和DialogFragment.STYLE_NO_TITLE定义在同一位置)。非常感谢你提供的解决方案。 - StefanK
1
如果我想要更改标题的背景,那么这是可能的吗? - MinceMan
5
请注意,您不能在片段的onCreate()方法中设置对话框标题,因为对话框尚未创建 :) - greg7gkb
2
@Rob Holmes 我想在对话框类的外部(我创建实例的地方)设置标题。例如:MyDialogFragment myFragment = new MyDialogFragment(); myFragment.getDialog().setTitle("myTitle"); myFragment.show(getFragmentManager(), "myTitle"); 但是这时getDialog()返回null。在这里有没有其他方法可以设置标题(而不需要自己编写setTitle方法)? - David Doria
1
我相信Jason下面的方法在一般情况下更正确。 - Michel
显示剩余2条评论

75

重写onCreateDialog并直接在Dialog上设置标题可以吗?像这样:

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    Dialog dialog = super.onCreateDialog(savedInstanceState);
    dialog.setTitle("My Title");
    return dialog;
}

9
我认为您的解决方案更好,因为片段不仅可以用于对话框。 - ruX
这个解决方案对于Xamarin.Android也非常有用。 - Shittu Joseph Olugbenga
还可以查看我的更近期的答案,它基于上面的代码:https://dev59.com/FG435IYBdhLWcg3w0Trc#41798042 - ban-geoengineering

15

Jason的回答 曾经对我有用,但现在需要添加以下内容以使标题显示。

首先,在你的 MyDialogFragment 的 onCreate() 方法中,添加:

setStyle(DialogFragment.STYLE_NORMAL, R.style.MyDialogFragmentStyle);

然后,在你的 styles.xml 文件中添加:

<style name="MyDialogFragmentStyle" parent="Theme.AppCompat.Light.Dialog.Alert">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">false</item>
    <item name="android:windowActionBar">false</item>
    <item name="android:windowNoTitle">false</item>
</style>

尝试了几个小时不同的方法,这是唯一一个对我有用的。

NB - 您可能需要将Theme.AppCompat.Light.Dialog.Alert更改为其他内容,以匹配您主题的样式。


Android.Support.V4.App.DialogFragment切换到Android.Support.V7.App.AppCompatDialogFragment后,设置android:windowNoTitle为*false*是不必要的,也不足以解决问题,因为这会导致重复的标题(即使我确保它只被设置一次)。 - samus

2

DialogFragment可以表示为对话框和活动。使用下面的代码,可以为两者都正确地工作

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    if (getShowsDialog()) {
        getDialog().setTitle(marketName);
    } else {
        getActivity().setTitle(marketName);
    }
}

1
你可以查看官方文档。我做的方式是这样的:
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
            .setTitle("My Title");
    LayoutInflater inflater = getActivity().getLayoutInflater();
    View view = inflater.inflate(R.layout.my_layout, null);
    builder.setView(view);

    return builder.create();
}

1
类似于Ban Geoengineering's answer,但有一些修改,所以不是在DialogFragment中编写特定主题,而是覆盖styles.xmlDialogFragment使用的默认样式。
androidx.fragment.app.DialogFragment中设置标题。
class EditBatteryLevelFragment:DialogFragment(),SelfClosingFragment.Host
{
    override fun onCreateView(
        inflater:LayoutInflater,container:ViewGroup?,savedInstanceState:Bundle?
    ):View
    {
        // set dialog title
        requireDialog().setTitle(R.string.edit_battery_level__title)

        // .....
        return someView
    }
}

在您的应用程序主题中的styles.xml中,覆盖android:dialogTheme,这是由DialogFragment实例使用的默认样式。
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <style name="AppTheme" parent="Theme.MaterialComponents">

        <!-- BONUS READING: override material colors here, too https://material.io/develop/android/theming/color -->

        <!-- override DialogFragment theme of those spawned by activities with this theme -->
        <item name="android:dialogTheme">@style/AppTheme.Dialog</item>

    </style>

    <!-- ... -->

styles.xml 中,还需要声明对话框主题,该主题将被 DialogFragment 实例使用。这个样式从 ThemeOverlay 继承非常重要,这样它将保留您应用程序的主题颜色。
    <!-- ... -->

    <!-- define the style for your dialog -->
    <style name="AppTheme.Dialog" parent="ThemeOverlay.MaterialComponents.Dialog">

        <!-- add a minimun width to the dialog, so it's not too narrow -->
        <item name="android:windowMinWidthMajor">@dimen/abc_dialog_min_width_major</item>
        <item name="android:windowMinWidthMinor">@dimen/abc_dialog_min_width_minor</item>

        <!-- display the title for dialogs -->
        <item name="android:windowNoTitle">false</item>

    </style>

</resources>

请确保生成 DialogFragment 的活动使用了定义的 AppTheme


1
完美答案!我只需要 <item name="android:windowNoTitle">false</item> 来显示标题并使对话框全屏。 - nhcodes

0
如果您正在使用视图绑定:
@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
    binding = YourDialogXmlBinding.inflate(getLayoutInflater());
    AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity());
    builder.setTitle("Your title here")
            .setView(binding.getRoot());
    return builder.create();
}

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