Android常用框架结构Android知识Android开发

android换肤原理解析

2017-05-14  本文已影响325人  大批

: )


**En**

首先来说说应用场景


需要解决的问题


皮肤包的生成

测试用布局 我用的是adb push

如何通过资源名字来获取到上面生成的皮肤包资源

public Resources(AssetManager assets, DisplayMetrics metrics, Configuration config) {
        this(null);
        mResourcesImpl = new ResourcesImpl(assets, metrics, config, new DisplayAdjustments());
    }
AssetManager assetManager = AssetManager.class.newInstance();
Method addAssetPath = assetManager.getClass().getMethod("addAssetPath", String.class);
        addAssetPath.invoke(assetManager, filePath);
/**
         * 皮肤包的位置
         */
        String filePath = Environment.getExternalStorageDirectory() +
                File.separator + "demo.skin";

        AssetManager assetManager = AssetManager.class.newInstance();
        Method addAssetPath = assetManager.getClass().getMethod("addAssetPath", String.class);
        addAssetPath.invoke(assetManager, filePath);

        Resources resources = new Resources(
                assetManager,
                orginResources.getDisplayMetrics(),
                orginResources.getConfiguration()
        );
private static final String SKIN_PAGNAME = "com.suse.skindemo";

    private String getNameString(Resources resources){
        int id = resources.getIdentifier("create_name","string",SKIN_PAGNAME);
        return resources.getString(id);
    }

    private ColorStateList getTitleColor(Resources resources){
        int id = resources.getIdentifier("title_text_color","color",SKIN_PAGNAME);
        return resources.getColorStateList(id);
    }

    private Drawable getContentDrawable(Resources resources){
        int id = resources.getIdentifier("demo","mipmap",SKIN_PAGNAME);
        return resources.getDrawable(id);
    }
访问皮肤包的资源

如何比较方便的使用?

LayoutInflater inflater = getLayoutInflater();
        LayoutInflaterCompat.setFactory(inflater, new LayoutInflaterFactory() {
            @Override
            public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {

                LayoutInflater layoutInflater = getLayoutInflater();
                AppCompatDelegate delegate = getDelegate();
                View view = null;
                try
                {
                    //public View createView
                    // (View parent, final String name, @NonNull Context context, @NonNull AttributeSet attrs)
                    if (sCreateViewMethod == null)
                    {
                        Method methodOnCreateView = delegate.getClass().getMethod("createView", sCreateViewSignature);
                        sCreateViewMethod = methodOnCreateView;
                    }
                    Object object = sCreateViewMethod.invoke(delegate, parent, name, context, attrs);
                    view = (View) object;
                } catch (NoSuchMethodException e)
                {
                    e.printStackTrace();
                } catch (InvocationTargetException e)
                {
                    e.printStackTrace();
                } catch (IllegalAccessException e)
                {
                    e.printStackTrace();
                }

                if (view == null)
                {
                    view = createViewFromTag(context, name, attrs);
                }
                return view;
            }
        });

最后给出两个开源项目吧,思路都是来自这两个项目

https://github.com/hongyangAndroid/ChangeSkin
https://github.com/fengjundev/Android-Skin-Loader


Nothing is certain in this life. The only thing i know for sure is that. I love you and my life. That is the only thing i know. have a good day

上一篇下一篇

猜你喜欢

热点阅读