主题不适用于片段

Posted

技术标签:

【中文标题】主题不适用于片段【英文标题】:Theme isn't applying in Fragment 【发布时间】:2015-07-09 05:42:01 【问题描述】:

我正在尝试在片段上应用特定主题。但由于某种原因,它没有发生。谁能指出我的代码中的错误?还是更好的解决方案?

styles.xml 中的主题:

<!-- Theme for trans actionbar -->
<style name="TransTheme" parent="@style/AppTheme">
    <item name="android:actionBarStyle">@style/TransActionbar</item>
    <item name="android:windowActionBarOverlay">true</item>
    <item name="actionBarStyle">@style/TransActionbar</item>
    <item name="windowActionBarOverlay">true</item>
</style>

@style/TransActionbar 在哪里:

<!-- Actionbar style for trans theme -->
<style name="TransActionbar" parent="@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse">
    <item name="android:background">@color/first_trans_actionbar</item>
    <item name="background">@color/first_trans_actionbar</item>
</style>

我想如何在 onCreateView() 方法中的片段中应用主题:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) 
    //set theme
    final Context contextWrapper = new ContextThemeWrapper(getActivity(), R.style.TransTheme);
    LayoutInflater localInflater = inflater.cloneInContext(contextWrapper);
    contentView = localInflater.inflate(R.layout.fragment_movie_detail,
            container, false);
    return contentView:

出于某种原因,Fragment 保留了旧主题..

编辑

所以基本上问题归结为:如何在 Activity 的一个片段中使 Actionbar 透明(和覆盖模式)?

【问题讨论】:

您是否在清单中应用您的主题? @Sassa 我试图在导航到另一个片段后立即更改清单中应用的主题。 我明白了;您是在 application 还是在清单中的 activity 标记中应用原始主题? @Sassa 在应用程序标签中应用了一个整体主题,我尝试用上面的代码覆盖该主题。但它似乎不起作用。 工具栏是 v7 支持库的一部分,所以是的,它可以在 Android 2.1.x 上运行。 【参考方案1】:

我猜你想在同一个 Activity 中切换两个(或更多)Fragments,其中每个都可能需要 ActionBar 覆盖或不覆盖,并且具有不同的背景,具体取决于当前Fragment

让我们把最重要的事情弄清楚:到目前为止,您还不能在运行时更改 Activity 的主题。

您仍然可以通过执行以下操作相对轻松地完成您所追求的目标:

    Activity 主题设置为使用覆盖的ActionBar。 对于那些不希望覆盖ActionBarFragments,在其布局xml 中,将顶部填充/边距设置为等于ActionBar 高度。理想情况下,您只需引用the dimension resource for action bar height。对于那些您希望 ActionBar 覆盖它们的 Fragments,您应该在其布局 xml 的顶部没有填充/边距。 当您切换Fragments 时,通过调用getActionBar()(或getSupportActionBar,如果您正在使用支持库)更改ActionBar 的背景颜色,然后调用.setBackgroundColor(Color.TRANSPARENT) 或您需要的任何颜色使用getResources().getColor(R.colors.some_color) 的资源。您可以通过动画颜色变化来寻求比突然切换更花哨的东西,但这超出了这个问题的范围。

    ...

    利润!

编辑:Toolbar

如果你想使用Toolbar,方法是把它放在一个单独的布局xml中,你&lt;include&gt;在你的Activity布局中,并给它一些你可以通过代码引用的ID .确保 Activity 根布局具有 Z 顺序,例如 RelativeLayoutFrameLayout,并将工具栏 &lt;include&gt; 定位在 Y 轴的顶部(alignParentTop 用于 RelativeLayoutlayout_gravity="top" 用于FrameLayout),Toolbar &lt;include&gt; 放在您将Fragments 放入其中的任何布局之后,以便覆盖它们。

Activity onCreate 里面这样做:

Toolbar yourToolbar = (Toolbar) findViewById(R.id.your_toolbar);
yourToolbar.setBackgroundColor(<whatever color you want>);
setSupportActionBar(yourToolbar);
ActionBar actionBar = getSupportActionBar();
actionBar.setHomeButtonEnabled(true/false);
actionBar.setDisplayHomeAsUpEnabled(true/false);
actionBar.setTitle(<whatever title you want>);

否则,我原始答案中的所有内容仍然有效。

【讨论】:

这是一个非常好的建议!您会推荐什么:使用此解决方案或工具栏? 我将更新我的答案,以阐明它如何与工具栏啮合:)【参考方案2】:

感谢 Tomask https://***.com/a/34686405/5502121 您可以在运行时更改片段的活动主题中的属性。只需在片段使用您的自定义样式膨胀并应用到当前主题之前覆盖它们即可:

    比如说,您有一些属性要应用到片段中,例如波纹颜色。使用此属性创建样式: 在 values/styles.xml

    <style name="colorControlHighlight_blue">
       <item name="colorControlHighlight">@color/main_blue_alpha26</item>
    </style>
    

    onCreateView()膨胀之前的片段中

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
       getContext().getTheme().applyStyle(R.style.colorControlHighlight_blue, true); //blue ripple color
       View view = inflater.inflate(R.layout.my_fragment_layout, container, false);
       return view;
    
    

此样式仅适用于该片段

【讨论】:

【参考方案3】:

这是您的解决方案,

如果您只想为特定的活动片段应用样式,那么只需在调用片段的onCreateView()onAttach() 之前添加此行,

getActivity().getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
getActivity().getWindow().setStatusBarColor(Color.TRANSPARENT);

并设置透明状态栏,然后将 false 设置为根布局的fitsSystemWindows 属性,

android:fitsSystemWindows="false"

它对我有用,希望对其他人有帮助。

【讨论】:

【参考方案4】:

查看支持库 22.1 的更改here,我看到您现在可以将主题应用于任何视图(这也意味着它可以应用于片段)。所以我相信如果你使用新的 appcompat 并将所需的主题设置为片段的根视图,它会成功的。

但是我可以看到您正在尝试更改 ActionBar 的样式...我认为这不会起作用,因为 ActionBar 是由您的 Activity 而不是您的 Fragment 创建的,因此它的样式来自你的活动。为此,您需要更改 Activity 中的主题。

【讨论】:

我正在尝试使用 ContextWrapper 在 onCreateView() 方法中更改我的活动主题。但它不起作用。 当然不会。 Activity 在调用 onCreateView 时已经创建,因为它是创建片段的 Activity(而不是环绕方式),一旦创建了 Activity,您就无法更改主题。您需要重新加载整个活动 ***.com/questions/23635824/… 我的印象是,当您使用包装新主题的 ContextWrapper 为片段充气时,它会使用该主题为片段充气。那么实现这一目标的不同方法是什么?基本上,如果我可以在特定片段加载后立即使操作栏透明,那就没问题了。 您需要透明还是完全隐藏?【参考方案5】:

我认为您应该将主题应用于您的活动而不是片段。

尝试 setTheme(R.style.TransTheme);以上 setContentView();

【讨论】:

这里的问题是我不希望 Activity 主题是 R.style.TransTheme,只是该 Activity 中的一个片段。

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

Vuetify 主题不适用于自定义主题

UIActivityViewController 主题不适用于 Outlook

主题不适用于 Android 上的 DialogFragment

Wordpress 5.4 主题编辑器适用于 LOCALHOST 但不适用于 LIVE 主题编辑器站点

Sass lightness() 函数不适用于 TailwindCSS 主题变量

Magento 主题例外不适用于类别和产品页面