换肤框架学习总结

学习源

鸣谢:http://www.jianshu.com/p/5eac94143bd6

源码地址

https://github.com/jigongdajiang/FunDemo/tree/master

场景分析

1.黑夜白天模式
2.从服务器下载皮肤资源,加载任意皮肤

核心代码分析
1.根据皮肤文件自己创建资源加载类 Resources AssetManager。核心代码如下:
/**
 * 根据皮肤资源路径创建对应的Resources
 */
public SkinResource(Context context, String skinPath) {
        try{
            Resources surperResource = context.getResources();
            Configuration configuration = new Configuration();
            DisplayMetrics displayMetrics = surperResource.getDisplayMetrics();
            AssetManager assetManager = AssetManager.class.newInstance();
            //添加本地下载好的皮肤
            Method methodAddAssetPath = AssetManager.class.getDeclaredMethod("addAssetPath",String.class);
            methodAddAssetPath.setAccessible(true);
            methodAddAssetPath.invoke(assetManager,skinPath);
            mResources = new Resources(assetManager,displayMetrics,configuration);
            //获取皮肤apk的包名
            mPackageName = context
                    .getPackageManager()
                    .getPackageArchiveInfo(skinPath, PackageManager.GET_ACTIVITIES)
                    .packageName;
        }catch (Exception e){
            e.printStackTrace();
        }
}
/**
 * 根据资源名称 如 @color/main_big_color中的main_big_color 解析资源属性进行重新设置
 */
@Override
public void skin(View view, String resName) {
            if(view != null && view instanceof TextView){
                SkinResource skinResource = getSkinResource();
                ColorStateList color = skinResource.getColorByName(resName);
                if(null != color){
                    ((TextView)view).setTextColor(color);
                }
            }

}
2.连接View的创建,然后截取其属性信息,用第一步的新资源装在器重置View的皮肤属性信息。核心代码如下:
/**
 * 通过源码得知,指定自己的LayoutInflaterFactory可以拦截View的创建
 */
private void installMyViewFactory() {
        if (!SkinManager.getInstance().isInit()) {
            SkinManager.getInstance().init(this);
        }
        LayoutInflater layoutInflater = LayoutInflater.from(this);
        if (layoutInflater.getFactory() == null) {
            //仿照AppCompatActivity 的方法,这里一旦自己设置了,将不会走AppCompatActivity中的工厂
            LayoutInflaterCompat.setFactory(layoutInflater, this);
        }

}

/**
 * 仿照系统的View创建过程,以实现兼容性
 */
@Override
public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
        // 创建View
        View view = createView(parent, name, context, attrs);
//        Log.e(TAG,"View-->"+view);
        // 解析属性 src background textColor
        // 1. 一个Activity 对应对个SkinView
        List<SkinAttr> skinAttrs = SkinAttrSupport.getSkinAttrs(context, attrs);
        if (null != view) {
            SkinView skinView = new SkinView(view, skinAttrs);
            // 统一交给SkinManager去管理
            manageSkinView(skinView);
            String currentSkinPath = SkinSpUtil.getInstance().getCurrentSkinPath();
            if (SkinConfig.SKIN_FILE_QUALIFIED == SkinManager.getInstance().autoLoadCheckSkinPath(currentSkinPath)) {
                //自动切换皮肤
                skinView.skin();
            }
        }
        return view;
    }
框架的使用

1.所有需要换肤的Activity继承自BaseSkinActivity
2.下载完皮肤直接调用SkinManager.getInstance().loadSkin(skinPath)即可

/**
 * 点击换肤按钮
 */
public void skinChange(View view) {
        String skinPath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "black.skin";
        int result = SkinManager.getInstance().loadSkin(skinPath);
        if (SkinConfig.SKIN_CHANGE_SUCCESS == result) {
            Toast.makeText(this, "换肤成功", Toast.LENGTH_LONG).show();
        }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值