【发布时间】:2020-04-09 22:04:48
【问题描述】:
我公司的应用程序支持在运行时动态更改主题,而无需重新启动当前的 Activity。它通过遍历视图树并将样式应用于配置为支持它的每个视图来实现此目的。然而,我遇到的问题是,在查看视图树时,永远找不到为 Spinners 显示的下拉视图。这是从 Activity 中查找每个 View 的代码:
void applyTheme(final int resourceId) {
setTheme(resourceId);
// Apply the theme to the activity's view.
styleView(findViewById(android.R.id.content));
// Apply the theme to any dialog fragments.
final List<Fragment> fragments = getSupportFragmentManager().getFragments();
for (final Fragment fragment : fragments) {
if (fragment instanceof DialogFragment) {
final Dialog dialog = ((DialogFragment)fragment).getDialog();
if (dialog != null) {
final Window window = dialog.getWindow();
if (window != null) {
styleView(window.getDecorView());
}
}
}
}
}
void styleView(final View view) {
// Apply styling here.
...
// Recursively find all children and apply the theme to them.
if (view instanceof ViewGroup) {
final ViewGroup viewGroup = (ViewGroup)view;
for (int i = 0; i < viewGroup.getChildCount(); i++) {
styleView(viewGroup.getChildAt(i));
}
}
}
无论父 Spinner 定义在 Activity、Fragment 还是 DialogFragment 中,都找不到下拉视图。如果下拉视图对用户可见,是否有任何方法可以实际检索对它们的引用?
【问题讨论】:
-
Spinner的下拉菜单实际上是一个PopupWindow,其中包含一个ListView。PopupWindow是一个与Activity完全独立的窗口,因此它的View层次结构不附加到Activity的,这就是为什么您在遍历中没有得到那些Views .然而,即使你可以,我认为它不会很好地工作。首先,PopupWindow和其中的ListView每次显示时都会重新创建,因此直接对这些Views 进行的任何修改都不会持续存在。其次,我会假设您的主题切换是由某处的某个点击事件触发的。 -
如果是这样,那么我认为下拉菜单在发生这种情况时不会可见,因为单击下拉菜单或其他任何地方会导致它立即关闭。考虑到这两种情况,我认为一个可行的选择是简单地在
Spinner上设置一个新的Adapter实例,并在Activity周围传递一个ContextThemeWrapper,并使用适当的样式。或者,您可以创建一个自定义的Adapter类,在其中设置每个项目View的样式,类似于您现在的样式。在这种情况下,您不一定需要每次都创建一个新实例。 -
用户既可以选择特定主题,也可以选择根据一天中的时间自动更改主题。在后者的情况下,当切换发生时,微调器可能会打开,使下拉菜单的主题与微调器实际所在的视图不同。微调器为下拉菜单返回的视图实际上是一个自定义视图,其构造函数适用样式,所以只要我可以更新已经实例化的视图,那么我不需要让适配器应用样式。
-
啊,好吧,那我明白为什么要担心了。好吧,真的没有像你一样干净,非hacky的方法来获取那些
Views,因为PopupWindow和ListView都没有公开曝光。不过,自定义Adapter仍然是一个可行的选项,因为您可以在主题开关上调用notifyDataSetChanged(),并使用getView()或getDropDownView()中的当前样式实例化新的下拉列表Views,具体取决于是否为下拉项设置了单独的布局。 -
哦,很酷。 :-) 除了给出一个非常广泛的解决方案大纲之外,我并没有真正做任何事情。当您找到适合您的东西时,请随时自己发布答案。我敢肯定,一个具体的例子对将来的某个人会很有帮助,现在每个人都在做暗/亮,
DayNight主题的东西。不过谢谢。我真的很感激这个提议。很高兴我能给你一些建议。干杯!
标签: java android android-view android-spinner