为片段设置主题

我正在为一个片段设置主题。

在清单中设置主题不起作用:

android:theme="@android:style/Theme.Holo.Light"

从以前的博客来看,似乎我必须使用 ContextThemeWrapper。有人能给我举个例子吗?我什么都找不到。

112762 次浏览

在清单中设置主题通常用于活动。

如果你想为片段设置主题,在片段的 onGetLayout ()中添加下面的代码:

override fun onGetLayoutInflater(savedInstanceState: Bundle?): LayoutInflater {
val inflater = super.onGetLayoutInflater(savedInstanceState)
val contextThemeWrapper: Context = ContextThemeWrapper(requireContext(), R.style.yourCustomTheme)
return inflater.cloneInContext(contextThemeWrapper)
}

请确保在清单中设置了 android:minSdkVersion="11"。这可能是为什么 大卫的例子不适合你的原因。

另外,为 <application>标记设置 android:theme="@android:style/Theme.Holo.Light"属性,为 没有设置 <activity>标记。

另一个可能的问题可能是在使用 ContextThemeWrapper()时获取上下文的方式。如果您使用类似 getActivity().getApplicationContext()的东西,只需将其替换为 getActivity()即可。

通常,Theme. Holo 应该应用于链接到 MainActivity 的片段。

请注意,当您想为片段应用 与众不同主题时,您使用了 ContextThemeWrapper。如果您提供来自 MainActivity 的代码片段,并在其中添加片段,可能会有所帮助。


一些有用的连结:

片段中的自定义 ListView 不符合父主题

片段从它的活动中获取它的主题。每个片段都被分配到它所在的活动的主题中。

主题应用于 Fragment.onCreateView 方法,您的代码在该方法中创建视图,这些视图实际上是使用主题的对象。

在 Fragment.onCreateView 中,您得到了 Layoutflater 参数,该参数使视图膨胀,并且它保存用于主题的 Context,实际上这是 Activity。因此,您的膨胀视图使用 Activity 的主题。

要覆盖主题,您可以调用 CloneInContext,它在文档中提到它可能用于更改主题。您可以在这里使用 ContextThemeWrapper。 然后使用克隆的充气器来创建片段视图。

我还试图让我的片段对话框显示与其活动不同的主题,并遵循 这个解决方案。像评论中提到的一些人一样,我没有让它工作,对话框不断显示清单中指定的主题。问题在于,我是在 onCreateDialog方法中使用 AlertDialog.Builder构建对话框的,所以没有使用我链接到的答案中显示的 onCreateView方法。当我实例化 AlertDialog.Builder时,我使用 getActivity()在上下文中传递,而我应该使用实例化的 ConstextThemeWrapper

下面是我的 onCreateDialog 的代码:

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Create ContextThemeWrapper from the original Activity Context
ContextThemeWrapper contextThemeWrapper = new ContextThemeWrapper(getActivity(), android.R.style.Theme_DeviceDefault_Light_Dialog);
LayoutInflater inflater =   getActivity().getLayoutInflater().cloneInContext(contextThemeWrapper);
// Now take note of the parameter passed into AlertDialog.Builder constructor
AlertDialog.Builder builder = new AlertDialog.Builder(contextThemeWrapper);
View view = inflater.inflate(R.layout.set_server_dialog, null);
mEditText = (EditText) view.findViewById(R.id.txt_server);
mEditText.requestFocus();  // Show soft keyboard automatically
mEditText.setOnEditorActionListener(this);
builder.setView(view);
builder.setTitle(R.string.server_dialog);
builder.setPositiveButton(android.R.string.ok, this);
Dialog dialog = builder.create();
dialog.setCanceledOnTouchOutside(false);
return dialog;
}

我最初将 AlertDialog.Builder实例化如下:

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

我改成了:

AlertDialog.Builder builder = new AlertDialog.Builder(contextThemeWrapper);

更改之后,片段对话框显示了正确的主题。因此,如果其他任何人也有类似的问题,并且正在使用 AlertDialog.Builder,那么请检查传递给构建器的上下文。希望这个能帮上忙!:)

创建一个 java 类,然后使用 onCreate 方法中希望更改主题的布局。那就像往常一样在清单上写明

用于应用我刚才使用的单个样式

getContext().getTheme().applyStyle(styleId, true);

在片段 onCreateView()之前膨胀片段的根视图,它为我工作。

你可以试试这个做棒棒糖 附件

Final Window 窗口 = activity.getWindow () ; SetStatusBarColor (myStatusBarColor)

并在 ondettach 中将其设置回默认值

我尝试了大卫建议的解决方案,它确实奏效,但并非在所有情况下都奏效:
1.对于添加到堆栈中的第一个片段具有活动的主题,而不是在 onCrateView 中定义的主题,但是对于我添加到堆栈中的第二个片段,更正它们应用于该片段。< br/> < br/> 2.在第二个片段,他们显示正确,我做了以下我强制应用程序被关闭,清理内存,重新打开应用程序,当活动是重新创建的片段片段改变了他们错误的他们的活动,而不是相同的设置在 onCrateView 的片段。

为了解决这个问题,我做了一个小小的修改,并用一个 null 替换了 flater.flate 中的容器参数。

我不知道如何在一些情况下使用容器视图的上下文充气器。

注意——我使用 android.support. v4.app. Fragment & android.support. v7.app. AppCompatActivity。

@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.yourCustomTheme);


// clone the inflater using the ContextThemeWrapper
LayoutInflater localInflater = inflater.cloneInContext(contextThemeWrapper);


// inflate the layout using the cloned inflater, not default inflater
return localInflater.inflate(R.layout.yourLayout, null, false);
}

我在片段的布局文件中使用 android:theme = "@style/myTheme"解决了这个问题。 例如,这改变了 LinearLayout的风格和它的内容,但除了 LinearLayout之外没有任何东西。因此,为了用任何样式装饰整个片段,将主题应用到它最外层的父布局。

注意: 如果你还没有找到解决方案,你可以尝试一下。

           <LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:theme = "@style/myTheme" >


<TextView
android:id="@+id/tc_buttom_text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Time elapsed"/>


<TextView
android:id="@+id/tc_buttom_text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="00:00:00 00"/>
</LinearLayout>

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

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

如果要设置透明状态栏,请将根布局的 假的属性设置为 fitsSystemWindows,

android:fitsSystemWindows="false"

我知道这有点晚了,但它可能会帮助别人,因为这帮助了我。您还可以尝试在片段的 onCreatView 函数中添加下面的代码行

    inflater.context.setTheme(R.style.yourCustomTheme)

我通过在调用膨胀器之前在片段上下文上设置主题来使它工作。

注意: 这是 Xamarin 的一个例子。Android 与 MvvmCross 的结合。我不能100% 确定这是否也适用于 Java 程序员。不过你可以试试:)

public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
Context.SetTheme(Theme);


base.OnCreateView(inflater, container, savedInstanceState);


var view = this.BindingInflate(FragmentLayoutId, container, false);


// Doing some other stuff


return view;
}

SetTheme 扩展方法代码

public static void SetTheme(this Context context, AppThemeStyle themeStyle)
{
var themeStyleResId = themeStyle == AppThemeStyle.Dark ? Resource.Style.AppTheme : Resource.Style.AppTheme_Light;


context.SetTheme(themeStyleResId);
}

我希望这能帮助一些人,干杯!

在你想要不同主题的片段中使用这个:

@Override
public void onAttach(@NonNull Context context) {
context.setTheme(R.style.your_them);
super.onAttach(context);
}