场景:
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<WeakReference<SkinAttr>> skinAttrs = new ArrayList<WeakReference<SkinAttr>>();
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<SkinAttr> 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];
}
}
}