1. Implement layout monitoring with your own Layout
public class SkinActivity implements Layout{
SkinLayoutInflater skinLayoutInflator;
protected void onCreate(Bundle saveInstanceState){
skinLayoutInflator = new SkinLayoutInflater();
LayoutInflaterCompat.setFactory(getLayoutoutInflater().skinLayoutInflater);
}
public void update(){
SkinManager.loadPath("skin.apk");
SkinManager.update();
}
}
2. Implement your own LayoutInflaterFactory
public class SkinLayoutInflater implements LayoutInflaterFactory{
SkinLayoutInflater skinLayoutInflater;
private
public View createView(View parent,String name,String Context,AttributeSet attrs){
View view = null;
if(name.indexOf(".")!=-1)){//custom control
view = createView(context,attrs,name);
}else{//Reflection construction system control
for(String pre:prefixList){
view = createView(context,attrs,pre+name);
if(view == null){break;}
}
}
}
//Reflect View
public View createView(String name,String Context,AttributeSet attrs){
Class viewClazz = context.getClassLoader().loadClass(name);
Contructor<? extends view> contructor = viewClazz.getContructor(new Class[](Context.class,AttrubuteSet.class));
contructor.setAccessible (true);
}
//Apply the color obtained from the apk plugin
public void apply(){
for(SkinItem skinItem :list){
if("textColor".equals(skinItem.getAttrName())){
if(view instanceof TextView){
((TextView)view).setTextColor(skinItem.getId());
}else{
((TextView)view).setTextColor(SkinManager.getInstance().getColor(skinItem.getId()));
}
}
}
}
//The wrapper class of skinitem
class SkinItem{
private String attrName;
private String attrValue;
String String attrType;
int id;
}
private void parseView(Context context,AttributeSet attrs,View view,String name){
for(int i=0;i<attrs.getAttributeCount();i++){
String attrName = attrs.getAttributeName(i);
String attrValue = attrs.getAttributeValue(i);
if("background".equal(attrName)||"textColor".equal(attrName)){
int id = Integer.parseInt(attrValue.substring(1));
String entryName = context.getResources().getResourceEntryName(id);
String typeName = context.getResources().getResourceTypeName(id);
SkinItem skinItem = new SkinItem (attrName, id, entryName, typeName);
list.add(skinItem);//Collect skinned ITem
}
}
if(!list.isEmpty){
SkinView skinview = new SkinView
}
}
class SkinManager{
private Context context;
private Resource skinResource;
private String skinPackageName;
private static SkinManager ourInstance = new SkinManager();
public SkinManager(){
}
public static SkinManager getInstance(){return ourInstance;}
public void init(Context context){
this.context = context.getApplicationContext();
}
//Load apk path
public void loadSkin(File apkPath){
PackageManager packageManager = coontext.getPackageManager();
PackageInfo packageInfo = packageManager.getPackagerArchiveInfo(apkPath.getAbsolutePath,PackageManager.GET_ACTIVITIE);//This is very important, load apk package information and package resources according to packageManage
skinPackageName = packageInfo.packageName;
AssetManager assetManager = AssetManager.class.newInstance();
Method addAssetPath()=assetManager.getClass.getClass.getMethod("addAssetPath",String.class);
addAssetPath.invoke(assetManager.apkPath.getAbsoluteFile());
skinResource = new Resource(assetManager,context.getResources().getDisplayMetries,context.getResources().getContext);
}
// update each view
public void update(){
for(View view : cacheMap.keySet()){
SkinView skinitem = cacheMap.get(view);
skinItem.apply();
}
}
public int getColor(int resId){
if(skinResource == null){
return resId;
}
String resName = context.getResources().getResoucesEntryName(resId);//Get the resource name
int skinId = skinResource.getIndentifier(resName,"color",skinPackageName);//Get the skin ID through the resource name
return skinResource.getColors(resId);
}
}
class SkinView{
private View view;
private List<SkinItem> list;
public SkinView(View view,List<SkinItem> list>) {
this.view = view;
this.list = list;
}
//Update the ViewItem that needs to be skinned
public void apply(){
for(SkinItem skinItem :list){
if("textColor".equals(skinItem.getAttrName())){
if(view instanceof TextView){
(TextView)view .setTextColor(skinItem.getId());
}else if(view instanceof Button){
(TextView)viwe.setTextColor(skinItem.getId);
}
}
}
}
}
}