在运行时覆盖资源问题代码关于替代方法的一句话
问题
我希望能够在运行时覆盖我的应用资源,例如R.colour.brand_colour或R.drawable.ic_action_start。我的应用程序连接到CMS系统,该系统将提供品牌颜色和图像。一旦应用程序下载了CMS数据,它需要能够重新蒙皮。
我知道你要说什么 - 在运行时覆盖资源是不可能的。
除了它有点。特别是,我发现了2012年的学士论文,它解释了基本概念 - Android中的活动类扩展,其中包含attlebaseContext方法。您可以重写 attachBaseContext 以使用您自己的自定义类包装 Context,该自定义类将覆盖 getColor 和 getDrawable 等方法。你自己的getColor实现可以按照它想要的方式查找颜色。书法库使用类似的方法来注入自定义布局膨胀器,该膨胀器可以处理加载自定义字体。ContextWrapper
代码
我创建了一个简单的活动,它使用这种方法来覆盖颜色的加载。
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(new CmsThemeContextWrapper(newBase));
}
private class CmsThemeContextWrapper extends ContextWrapper{
private Resources resources;
public CmsThemeContextWrapper(Context base) {
super(base);
resources = new Resources(base.getAssets(), base.getResources().getDisplayMetrics(), base.getResources().getConfiguration()){
@Override
public void getValue(int id, TypedValue outValue, boolean resolveRefs) throws NotFoundException {
Log.i("ThemeTest", "Getting value for resource " + getResourceName(id));
super.getValue(id, outValue, resolveRefs);
if(id == R.color.theme_colour){
outValue.data = Color.GREEN;
}
}
@Override
public int getColor(int id) throws NotFoundException {
Log.i("ThemeTest", "Getting colour for resource " + getResourceName(id));
if(id == R.color.theme_colour){
return Color.GREEN;
}
else{
return super.getColor(id);
}
}
};
}
@Override
public Resources getResources() {
return resources;
}
}
}
问题是,它不起作用!日志记录显示对加载资源(如布局/activity_main和 mipmap/ic_launcher但从不加载 color/theme_colour 的调用。上下文似乎用于创建窗口和操作栏,而不是活动的内容视图。
我的问题是 - 布局膨胀器从哪里加载资源,如果不是活动上下文?我还想知道 - 有没有可行的方法来覆盖运行时颜色和可绘制对象的加载?
关于替代方法的一句话
我知道可以通过其他方式从CMS数据中主题化应用程序 - 例如,我们可以创建一个方法,然后在我们的内部有一堆代码,如下所示:getCMSColour(String key)
onCreate()
myTextView.setTextColour(getCMSColour("heading_text_colour"))
对于可绘制对象、字符串等,可以采用类似的方法。但是,这将导致大量的样板代码 - 所有这些都需要维护。修改 UI 时,很容易忘记在特定视图上设置颜色。
包装上下文以返回我们自己的自定义值是“更清晰”的,并且不易损坏。在探索替代方法之前,我想了解为什么它不起作用。