如何从 android 中的另一个应用程序资源更改主题?
How to change theme from another app resource in android?
我知道有一种方法可以通过在 styles.xml 中定义来设置主题并像那样使用它
setTheme(android.R.style.MyTheme);
但是,我想从我开发的另一个应用程序中获取主题。我知道资源名称,实际上我可以使用此代码块获取主题 ID;
Resources res = getPackageManager().getResourcesForApplication("com.example.theme");
int resThemeId = res.getIdentifier("my_theme","style","com.example.theme");
调试时,我发现 resThemeId 不为零。
然后,我需要最后的命令来设置这个主题。在 super.onCreate() 函数之前,我尝试实现这个方法,但它似乎不起作用
setTheme(resThemeId);
但不是这样,如果我写下面的语句,我工作正常
setTheme(android.R.style.Theme_Holo_Light);
那么,如何使用来自不同包资源的主题?
如评论中所述,您可以从其他应用程序访问资源,但使用其他应用程序主题将不起作用。
既然有证据总是好事,让我们看看源代码(我使用了 API 24 个源代码)
在 Activity
上调用 setTheme()
将在 ContextThemeWrapper
父 class 中调用 initializeTheme()
,这将最终调用 onApplyThemeResource(..)
反过来将尝试通过调用 theme.applyStyle(resId, true)
从资源中加载实际的主题数据
通过包装器跟踪链 Resources.Theme
我们可以在 ResourcesImpl.ThemeImpl
中看到以下内容,其中调用 AssetManager
将样式加载到主题中:
void applyStyle(int resId, boolean force) {
synchronized (mKey) {
AssetManager.applyThemeStyle(mTheme, resId, force);
mThemeResId = resId;
mKey.append(resId, force);
}
}
这是您尝试从其他应用加载 foreign 主题的地方。
由于您需要使用的大多数方法都是静态调用或封装本地方法,因此似乎没有任何方法可以实现您想要的(例如应用或创建新主题)
即使您通过在上下文 there is no accessible method to create or apply themes.
上使用 getAssets()
获得其他应用程序的 AssetManager
因此,使用其他应用程序资源的唯一方法是将资源添加到您的资源中。
So, what should I do to use a theme from different package resource?
出于多种原因,您不应该这样做。我写了一个简单的项目,表明只要包中包含您的 activity 使用的资源,它确实是可能的。
参见:https://github.com/jaredrummler/SO-41872033
基本上,您需要 return 来自 activity:
的包资源
public class MainActivity extends AppCompatActivity {
Resources resources;
@Override protected void onCreate(Bundle savedInstanceState) {
int themeResId = getResources().getIdentifier("AppTheme", "style", "com.example.theme");
if (themeResId != 0) {
setTheme(themeResId);
}
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override public Resources getResources() {
if (resources == null) {
try {
resources = getPackageManager().getResourcesForApplication("com.example.theme");
} catch (PackageManager.NameNotFoundException e) {
resources = super.getResources();
}
}
return resources;
}
}
这只是为了证明这是可能的。同样,我建议您避免这种情况。
你看过这个演示吗:Multiple Theme Material Design
您可以查看此演示以了解运行时主题更改。
希望对您有所帮助。
我知道有一种方法可以通过在 styles.xml 中定义来设置主题并像那样使用它
setTheme(android.R.style.MyTheme);
但是,我想从我开发的另一个应用程序中获取主题。我知道资源名称,实际上我可以使用此代码块获取主题 ID;
Resources res = getPackageManager().getResourcesForApplication("com.example.theme");
int resThemeId = res.getIdentifier("my_theme","style","com.example.theme");
调试时,我发现 resThemeId 不为零。
然后,我需要最后的命令来设置这个主题。在 super.onCreate() 函数之前,我尝试实现这个方法,但它似乎不起作用
setTheme(resThemeId);
但不是这样,如果我写下面的语句,我工作正常
setTheme(android.R.style.Theme_Holo_Light);
那么,如何使用来自不同包资源的主题?
如评论中所述,您可以从其他应用程序访问资源,但使用其他应用程序主题将不起作用。
既然有证据总是好事,让我们看看源代码(我使用了 API 24 个源代码)
在 Activity
上调用 setTheme()
将在 ContextThemeWrapper
父 class 中调用 initializeTheme()
,这将最终调用 onApplyThemeResource(..)
反过来将尝试通过调用 theme.applyStyle(resId, true)
通过包装器跟踪链 Resources.Theme
我们可以在 ResourcesImpl.ThemeImpl
中看到以下内容,其中调用 AssetManager
将样式加载到主题中:
void applyStyle(int resId, boolean force) {
synchronized (mKey) {
AssetManager.applyThemeStyle(mTheme, resId, force);
mThemeResId = resId;
mKey.append(resId, force);
}
}
这是您尝试从其他应用加载 foreign 主题的地方。
由于您需要使用的大多数方法都是静态调用或封装本地方法,因此似乎没有任何方法可以实现您想要的(例如应用或创建新主题)
即使您通过在上下文 there is no accessible method to create or apply themes.
上使用getAssets()
获得其他应用程序的 AssetManager
因此,使用其他应用程序资源的唯一方法是将资源添加到您的资源中。
So, what should I do to use a theme from different package resource?
出于多种原因,您不应该这样做。我写了一个简单的项目,表明只要包中包含您的 activity 使用的资源,它确实是可能的。
参见:https://github.com/jaredrummler/SO-41872033
基本上,您需要 return 来自 activity:
的包资源public class MainActivity extends AppCompatActivity {
Resources resources;
@Override protected void onCreate(Bundle savedInstanceState) {
int themeResId = getResources().getIdentifier("AppTheme", "style", "com.example.theme");
if (themeResId != 0) {
setTheme(themeResId);
}
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override public Resources getResources() {
if (resources == null) {
try {
resources = getPackageManager().getResourcesForApplication("com.example.theme");
} catch (PackageManager.NameNotFoundException e) {
resources = super.getResources();
}
}
return resources;
}
}
这只是为了证明这是可能的。同样,我建议您避免这种情况。
你看过这个演示吗:Multiple Theme Material Design
您可以查看此演示以了解运行时主题更改。
希望对您有所帮助。