为Fragment设置主题
问题的原因是作者想要为一个Fragment设置主题,但是单独使用getContext().getTheme().applyStyle(styleId, true)方法无效。解决方法是在onCreateView()方法中调用getContext().getTheme().applyStyle(styleId, true)方法,并在Fragment的根视图被加载之前执行。另外,需要注意的是getContext()方法的最低API要求是23,如果需要在较低的API上使用该方法,可以参考stackoverflow上的回答提供的解决方案。
为了应用单个样式,我只是在Fragment的onCreateView()方法中使用了如下代码:
getContext().getTheme().applyStyle(styleId, true);
在Fragment的根视图被加载之前执行这段代码对我有效。
对于getContext()方法,最低API要求是23。
如果遇到最低API问题,请参考这个回答中提供的解决方案:stackoverflow.com/questions/36736244/…
这是一个很好的解决方法。我在onAttach(Context)方法中添加了这段代码,这也会将主题应用到所有子Fragment中。
但是这样做可能会产生意想不到的后果,因为它修改了上下文(大多数情况下是Activity)的主题。未来的Activity加载视图(例如旋转后)将在整个应用中使用新的主题。
每个Fragment都从它所在的Activity中继承主题。在Fragment的onCreateView方法中应用主题,该方法是在代码创建视图时使用主题的地方。
在Fragment的onCreateView方法中,您会得到一个LayoutInflater参数,用于填充视图,并且它保存了用于主题的上下文,实际上这个上下文就是Activity。因此,您填充的视图将使用Activity的主题。
要覆盖主题,您可以调用LayoutInflater.cloneInContext方法,该方法在文档中提到可以用于更改主题。在这里,您可以使用ContextThemeWrapper。
然后使用克隆的inflater来创建Fragment的视图。
正如Google文档中所说:“...返回与给定上下文关联的崭新的LayoutInflater对象...”- developer.android.com/reference/android/view/...
在Android中,通常在清单文件中设置主题是针对Activity的。如果要为Fragment设置主题,可以在Fragment的onGetLayoutInflater()方法中添加以下代码:
override fun onGetLayoutInflater(savedInstanceState: Bundle?): LayoutInflater {
val inflater = super.onGetLayoutInflater(savedInstanceState)
val contextThemeWrapper: Context = ContextThemeWrapper(requireContext(), R.style.yourCustomTheme)
return inflater.cloneInContext(contextThemeWrapper)
}
然而,这种方法并不适用于所有情况。有些用户表示,即使按照上述方法设置了主题,Fragment仍然使用了在清单文件中指定的主题。原因在于,在清单文件中指定的主题是针对Activity的,而不是针对Fragment的。
在清单文件中指定的主题会应用于整个Activity及其包含的所有Fragment。因此,如果需要为特定的Fragment设置不同的主题,不能仅通过在Fragment中的代码中设置主题来实现。
一些用户提到,在运行时通过FragmentTransaction添加Fragment时,清单文件中指定的主题也会应用于Fragment。这意味着,如果通过代码动态添加Fragment,并且在清单文件中指定了主题,那么该主题会应用于Fragment。
此外,一些用户提到,在使用ActionBarSherlock库中的SherlockFragmentActivity时,上述方法可能不起作用。因此,在使用特定的第三方库时,需要注意主题设置的差异。
对于性能方面的问题,有用户提到是否应该缓存ContextWrapper。但是,没有提供确切的答案。
总之,要为Fragment设置主题,不能仅通过在Fragment中的代码中设置主题来实现。需要在清单文件中为Activity设置主题,并在运行时添加Fragment时,主题会自动应用于Fragment。但在某些情况下,可能需要注意特定的库或框架对主题设置的差异。