主题不适用于 Android 上的 DialogFragment

Posted

技术标签:

【中文标题】主题不适用于 Android 上的 DialogFragment【英文标题】:Theme not applying to DialogFragment on Android 【发布时间】:2012-05-22 09:40:35 【问题描述】:

我正在将旧 Dialogs 切换为 DialogFragment,但主题和样式似乎不起作用。

我正在使用兼容库 v4 中的 DialogFragment,并且在 onCreate 方法中我尝试调用 setStyle(style, theme);有很多不同的主题,但对话框总是在运行 android 4.0.3 的模拟器中显示为“旧”对话框(即,它不会在 Holo 主题中显示)。

还有什么我应该做的吗?使用兼容性库是否会禁用 Holo 主题或任何东西?如果是这种情况,我是否应该创建两个 DialogFragment,一个用于旧版本,一个用于新版本?

谢谢!


这是我的对话框的(简化的)代码。我已经尝试过 Theme_Holo_Dialog_NoActionBar 和 Theme_DeviceDefault_Dialog_NoActionBar,但 Android 4 模拟器总是将对话框显示为“旧”对话框,而不是使用 Holo 主题。我究竟做错了什么? :(

[...]
import android.support.v4.app.DialogFragment;
[...]

public class AlertDialogFragment extends DialogFragment 

  public static AlertDialogFragment newInstance(int id) 

    AlertDialogFragment f = new AlertDialogFragment();
    Bundle args = new Bundle();
    args.putInt("id", id);
    f.setArguments(args);

 

  @Override
  public void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    int style = DialogFragment.STYLE_NORMAL, theme = 0;
    theme = android.R.style.Theme_Holo_Dialog_NoActionBar;
    setStyle(style, theme);     
  

  @Override
  public Dialog onCreateDialog(Bundle savedInstanceState) 

    mId = getArguments().getInt("id");
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
        .setTitle(mTitle)
        .setMessage(mMessage)
        .setPositiveButton(getString(R.string.btn_ok), new DialogInterface.OnClickListener()       
            @Override
            public void onClick(DialogInterface dialog, int which) 
                dismiss();                  
            
        );
        return builder.create();
    

【问题讨论】:

你继承了什么风格,给我们看看styles.xml还有你的targetSdk是什么?它需要超过 11 我的目标是 SDK 14,我什至没有使用 styles.xml 文件,我只是在调用 setStyle(style, theme);在 DialogFragment 的 onCreate 方法中尝试多种样式和主题组合。例如,在我的“旧”对话框中,我使用了 android.R.style.Theme_DeviceDefault_Dialog_NoActionBar,它在 ICS 模拟器中显示为 Holo,但现在使用相同的主题却没有。 尝试隐式使用 Holo:android.R.style.Theme_Holo_Dialog 谢谢,我也试过了...没用:( 你必须编辑你的帖子,放一个你尝试过的代码示例,这样你更有可能得到一些答案 【参考方案1】:

您不应将 AlertDialog.Builder(Context, int) 构造函数与支持库一起使用,因为它仅从 API 11 开始可用。

要为对话框设置主题,请改用 ContextThemeWrapper,如下所示:

ContextThemeWrapper context = new ContextThemeWrapper(getActivity(), android.R.style.Theme_Holo_Dialog_NoActionBar);
AlertDialog.Builder builder = new AlertDialog.Builder(context);

【讨论】:

有没有人用自定义样式试过这个?当我传入预定义的 android 样式时,它可以工作,但如果我传入我自己的样式,则不行。(我的自定义样式是 Theme.Dialog 的子项) 如果您根本不使用构建器,则给出了另一种方法(对我来说适用于自定义样式):***.com/questions/13469084/…【参考方案2】:

我相信您需要在实际的 Dialog 而不是 Fragment 上设置主题

使用此构造函数创建您的 AlertDialog:

 AlertDialog.Builder(Context context, int theme)

 AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), theme)

【讨论】:

我正在尝试,它似乎正在工作,谢谢 :) 我只需要再做一些测试,然后我会发布结果并将您的答案标记为已接受。谢谢! 不完全是...最后我为每个 Android 版本创建了不同的 XML 布局文件,这似乎可以解决问题... 那并使用主题 AlertDialog.THEME_DEVICE_DEFAULT_LIGHT 而不是 android.R.style.Theme_Holo_Dialog_NoActionBar :) 警告:如果您也在使用 .setView(),则必须通过调用 getSystemService(Context.LAYOUT_INFLATER_SERVICE) 从相同的包装上下文中获取 LayoutInflater,以便主题也应用到那里。浪费了 2 个小时才找到答案。 对话框是在DialogFragment类上自动创建的,如何访问builder【参考方案3】:

我只是为此浪费了很多时间,但我终于找到了一种完全在 xml 中执行此操作的方法。

在应用程序主题中,对话框实际上是单独主题的。因此,要使用绿色按钮和绿色 EditText 提示设置所有 DialogFragment 的样式,您可以创建如下样式:

<style name="DialogTheme" parent="@android:style/Theme.Holo.Light.Dialog">
    <item name="android:buttonStyle">@style/button_green</item>
    <item name="android:textColorHint">@color/green</item>
</style>

然后将此主题作为 dialogTheme 添加到您的应用程序主题中

<style name="MyTheme" parent="android:Theme.Holo.Light">
    <item name="android:dialogTheme">@style/DialogTheme</item>
</style>

非常感谢写this post 的人向我展示了我一直在寻找的路径!

【讨论】:

没关系。但是我如何使用DialogFragment.setStyle 在运行时选择样式? @fatfatson 您需要在 onCreate 中应用 setStyle。既不在构造函数中,也不在 onCreateView 中。或者更好的是,只需使用您想要的任何样式覆盖 getTheme()。【参考方案4】:

这是一个更新的答案,使用 23 的目标 SDK 和 14 的最小 SDK,此代码非常适合我。

问题中代码的主要变化是在构造函数中设置主题,仅覆盖 onCreateDialog(),并使用 v7 支持库中的 AlertDialog 类。

使用此代码,绿色文本扁平(无边框)按钮显示在 4.4.4 上,而不是默认的带边框灰色按钮。

import android.support.v7.app.AlertDialog;
import android.app.Dialog;
import android.support.v4.app.DialogFragment;
import android.content.DialogInterface;
import android.os.Bundle;

public class MyDialog extends DialogFragment 

    String message;

    public MyDialog(String m) 
        message = m;
        int style = DialogFragment.STYLE_NORMAL, theme = 0;
        theme = android.R.style.Theme_Holo_Dialog_NoActionBar;
        setStyle(style, theme);
    

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) 

        return new AlertDialog.Builder(getActivity())
                .setMessage(message)
                .setPositiveButton("OK",
                    new DialogInterface.OnClickListener() 
                        public void onClick(DialogInterface dialog, int whichButton) 
                            ((EnterPhoneNumberActivity)getActivity()).doPositiveClick();
                        
                    
                )
                .setNegativeButton("EDIT",
                    new DialogInterface.OnClickListener() 
                        public void onClick(DialogInterface dialog, int whichButton) 
                            ((EnterPhoneNumberActivity)getActivity()).doNegativeClick();
                        
                    
                )
                .create();
    

在 AppCompatActivity 中的使用:

    String message = "test";
    if (message != null) 
        DialogFragment newFragment = new MyDialog(message);
        newFragment.show(getSupportFragmentManager(), "dialog");
    

【讨论】:

【参考方案5】:

您应该在“onCreateView”中编写这些代码。

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
      Bundle savedInstanceState) 
    getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
    View view = inflater.inflate(R.layout.dialog_your_theme, container);
    return view;

【讨论】:

虽然这个代码块可能会回答这个问题,但最好能稍微解释一下为什么会这样。

以上是关于主题不适用于 Android 上的 DialogFragment的主要内容,如果未能解决你的问题,请参考以下文章

为啥这个 CSS 不适用于 Android 上的 Chrome,但适用于其他任何地方?

使用 Compose 导航不适用于 Android 上的 Google 地图

为啥 shadowColor: '...' - 不适用于“react-native-drawer”组件的 Android 上的抽屉样式?

将 UTC 转换为 EST 不适用于 Android 上的夏令时

来自网络的“添加到日历”的href 不适用于Android 6.0+ 上的本机谷歌日历应用程序

为啥 RegisterMessageHandler 不适用于特定主题名称?