Android Fragments 设定片段的主题

olmpazwi  于 2022-11-24  发布在  Android
关注(0)|答案(1)|浏览(152)

我有以下两个主题:

<!-- Base application theme. -->
<style name="Theme.MyDemoApp" parent="Theme.MaterialComponents.DayNight.NoActionBar">
    <!-- Primary brand color. -->
    <item name="colorPrimary">@color/purple_500</item>
    <item name="colorPrimaryVariant">@color/purple_700</item>
    <item name="colorOnPrimary">@color/white</item>
    <!-- Secondary brand color. -->
    <item name="colorSecondary">@color/teal_200</item>
    <item name="colorSecondaryVariant">@color/teal_700</item>
    <item name="colorOnSecondary">@color/purple_500</item>
</style>

<!-- Base application theme with a prominent app bar incl. image -->
<style name="Theme.MyDemoApp.Prominent.Image" parent="Theme.MyDemoApp">

    <!-- Transparent status bar, so that the image extents to the status bar-->
    <item name="android:statusBarColor">@android:color/transparent</item>
    <item name="android:windowTranslucentNavigation">true</item>
</style>

主题Theme.MyDemoApp正在我的应用程序或实际上我的整个应用程序中使用。
一个Activity打开了一个特殊的片段。该片段使用了一个带有图像的突出应用栏,图像也显示在状态栏上。因此,我创建了一个名为Theme.MyDemoApp.Prominent.Image的主题,使我能够在状态栏上显示图像。
由于片段将从不同的活动和片段调用,我想将Theme.MyDemoApp.Prominent.Image设置为片段。我已经寻找了许多将主题设置为片段的解决方案,如:
1)的

@Override
public void onAttach(@NonNull Context context) {
    context.setTheme(R.style.Theme_MyDemoApp_Prominent_Image);
    super.onAttach(context);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    //create ContextThemeWrapper from the original Activity Context with the custom theme
    final Context contextThemeWrapper = new ContextThemeWrapper(getActivity(), R.style.Theme_MyDemoApp_Prominent_Image);

    //clone the inflater using the ContextThemeWrapper
    LayoutInflater localInflater = inflater.cloneInContext(contextThemeWrapper);
    
    return inflater.inflate(R.layout.fragment_demo_appbar_image, container, false);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    getContext().getTheme().applyStyle(R.style.Theme_MyDemoApp_Prominent_Image, true);
    return inflater.inflate(R.layout.fragment_demo_appbar_image, container, false);
}

直接在片段xml文件中设置主题

<androidx.coordinatorlayout.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    style="@style/Theme.MyDemoApp.Prominent.Image"
    android:theme="@style/Theme.MyDemoApp.Prominent.Image"
    >
<!-- bla bla bla bla -->
</androidx.coordinatorlayout.widget.CoordinatorLayout>

然而,以上尝试的解决方案没有一个对我有效。主题不会改变又名状态栏是不透明的。如果我把片段主题参数到活动主题,它的工作就像一个魅力,但这不是我打算做的。
问题是什么?我知道如何在片段中正确设置主题吗?

kx5bkwkv

kx5bkwkv1#

尝试return localInflater.inflate(...在2.尝试

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

    //create ContextThemeWrapper from the original Activity Context with the custom theme
    final Context contextThemeWrapper = 
        new ContextThemeWrapper(getActivity(), R.style.Theme_MyDemoApp_Prominent_Image);

    //clone the inflater using the ContextThemeWrapper
    LayoutInflater localInflater = inflater.cloneInContext(contextThemeWrapper);
    return localInflater.inflate(R.layout.fragment_demo_appbar_image, container, false);
}

编辑:现在我看问题更清楚了...
你正在尝试设置statusBarColorwindowTranslucentNavigation-那些是Activity的参数,不是Fragment.所以你的主题应该被应用到Activity,在FragmentView层/级别上设置主题(Fragment的子项,FragmentActivity的子项)通过Context Package 或以编程方式设置/通过XML“太低”,托管Activity不会应用这些属性
所以你必须为整个Activity设置Theme-当你的Fragment显示并返回默认值时,半透明的状态栏但您可以通过编程方式仅通过calling setTheme( before super.onCreate( call为整个Activity设置Theme,因此仅在最开始时,当您可能不确定是否会显示translucent-status-Fragment时...(例如,它可能会在运行时的某次点击中显示)
因此,您需要重新启动Activity,然后使用一些额外的标志自定义setTheme(,您的Fragment也应该弹出,然后在启动时...您可以使用为Intent传递的Bundle,在finish()调用后再次启动此Activity
我认为这太麻烦了,您的Fragment实际上应该是另一个Activity,它具有由XML设置的透明状态主题,也可以是某个transparet-Activity-theme的扩展,而不是您的"Theme.MyDemoApp"

相关问题