场景:
1.统一设计Activity风格
2.加载外部资源,替换应用风格
3.不重启Activity的情况下,替换应用风格
4.应用使用系统默认View,开发者进行代码重构,想要增加view的功能,使用自定义View代替,却不想更改布局文件。例如:AppcomptActivity在factory使用新的View替换,实现风格的变换
原理:
1.拦截view创建
1.1创建自定义View
1.2穿件默认View,加载新的资源文件,设置View的属性
class SkinFactory implements LayoutInflater.Factory { private Context context; Resources resources; ArrayList> skinAttrs = new ArrayList >(); public SkinFactory(Context context, Resources resources) { this.resources = resources; this.context = context; } @Override public View onCreateView(String name, Context context, AttributeSet attrs) {// 创建View-----------------------start View view = null; try { if (-1 == name.indexOf('.')) { if ("View".equals(name)) { view = LayoutInflater.from(context).createView(name, "android.view.", attrs); } if (view == null) { view = LayoutInflater.from(context).createView(name, "android.widget.", attrs); } if (view == null) { view = LayoutInflater.from(context).createView(name, "android.webkit.", attrs); } } else { view = LayoutInflater.from(context).createView(name, null, attrs); } } catch (Exception e) { e.printStackTrace(); view = null; }// 创建View-----------------------end if (view == null) { return null; } for (int i = 0; i < attrs.getAttributeCount(); i++) { String attributeName = attrs.getAttributeName(i); String attributeValue = attrs.getAttributeValue(i); TODO: 2/17/2017 find attr that can be change and set new attr if (resources != null) applyResource(resources, new SkinAttr(view, attributeName, attributeValue)); } return view; } public void resotreDefault() { for (WeakReference skinAttrWeakReference : skinAttrs) { SkinAttr skinAttr = skinAttrWeakReference.get(); if (skinAttr != null && skinAttr.getView() != null) { applyResource(context.getResources(), skinAttr); } } } public void applyResource(Resources resource, SkinAttr skinAttr) { } class SkinAttr { View view; String attributeName; String attributeValue; public SkinAttr(View view, String attributeName, String attributeValue) { this.view = view; this.attributeName = attributeName; this.attributeValue = attributeValue; } public String getAttributeName() { return attributeName; } public View getView() { return view; } public String getAttributeValue() { return attributeValue; } public String getAttributeValueType() { return attributeValue.split("/")[0]; } public String getAttributeValueName() { return attributeValue.split("/")[1]; } }}