gpt4 book ai didi

java - 如何查找微调器显示的下拉 View

转载 作者:行者123 更新时间:2023-12-01 17:30:30 24 4
gpt4 key购买 nike

我公司的应用程序支持在运行时动态更改主题,而无需重新启动当前 Activity。它通过遍历 View 树并将样式应用到配置为支持它的每个 View 来实现此目的。然而,我遇到的问题是,在浏览 View 树时永远找不到为微调器显示的下拉 View 。这是从 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 中定义,都找不到下拉 View 。如果下拉 View 对用户可见,是否有任何方法可以实际检索对它们的引用?

最佳答案

This answer为我提供了一种查找所有 View 的方法,包括 PopupWindows 的 View 。不幸的是,它使用了反射,并不能保证在所有 API 版本上都能工作,但它似乎可以在我们的应用程序支持的 API 上工作(我在 API 19 和 28 上进行了测试)。这是 applyTheme() 更改的结果:

private Object wmgInstance = null;
private Method getViewRootNames = null;
private Method getRootView = null;

private void applyTheme(final int resourceId)
{
setTheme(resourceId);

try
{
// Find all possible root views (the Activity, any PopupWindows, and Dialogs). This logic should work with APIs 17-28.
if (wmgInstance == null)
{
final Class wmgClass = Class.forName("android.view.WindowManagerGlobal");
wmgInstance = wmgClass.getMethod("getInstance").invoke(null, (Object[])null);

getViewRootNames = wmgClass.getMethod("getViewRootNames");
getRootView = wmgClass.getMethod("getRootView", String.class);
}

final String[] rootViewNames = (String[])getViewRootNames.invoke(wmgInstance, (Object[])null);

for (final String viewName : rootViewNames)
{
final View rootView = (View)getRootView.invoke(wmgInstance, viewName);
styleView(rootView);
}
}
catch (Exception e)
{
// Log the exception.
}
}

这个逻辑成功地允许我更新微调器的下拉 View (当它们在主题更改期间可见时)。但是,仍然存在一个问题,如果 Spinner 的下拉 View 是在主题更改发生之前创建的,但下拉列表在主题更改时关闭,则重新打开 Spinner 会显示使用旧主题的 View 。我处理此问题的方法只是在适配器的 getDropDownView() 内的 View 上调用 styleView()

关于java - 如何查找微调器显示的下拉 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61130974/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com