android 换肤(1)——插件式无缝换肤(解析鸿洋大神的换肤流程)

对于app换肤,这是一个常见而又常用的功能。虽然我做的项目中还没涉及到换肤,但是还是想研究下。

于是,下载了鸿洋大神的换肤demo来研究。
先看效果图:(尊重鸿洋大神的代码,效果图上原创)
这里写图片描述
鸿洋大神的换肤有两种:
1,ChangeSkin;侵入式换肤
2,AndroidChangeSkin;tag换肤

这两种我都分析过。各有各的好处。不过我还是推荐使用第一种。

博文后面我会比较这两种换肤的差异,以及为什么推荐使用第一种tag换肤的原因。

这两种换肤的核心方法其实是一样的,只不过怎么获取需要换肤的资源的方法不同而已。

先来分析关键代码:

先看项目目录:
java文件

java文件

资源文件

我们可以从资源的命名看出来,资源的差异在于后缀名的不同,这是app内部换肤的关键,根据后缀名不同来区分。

而插件式换肤,也就是获得sd卡里的apk文件,然后获得其中的资源文件进行换肤的资源命名也是遵循这个规则。

1,接口

ISkinCallback


/**
 * 设置皮肤状态回调
 */
public interface ISkinCallback {
   
    void onStart();//开始

    void onError(Exception e);//错误

    void onComplete();//完成
}

ISkinListener

/**
 * 通知皮肤设置的接口
 */
public interface ISkinListener {
   
    //这个接口用于通知应该改变皮肤资源了
    void onSkinChanged();
}

执行换肤的时候其实就是调用的ISkinListener接口而已。所有继承它的view都能得到换肤的通知。

2,保存用户的皮肤喜好设置

SkinSharedPreferencesUtils 类

/**
 * 保存用户对该app的皮肤设置
 */
public class SkinSharedPreferencesUtils {
   
    private SharedPreferences sharedPreferences;//键值对实例

    public SkinSharedPreferencesUtils(Context context) {
        sharedPreferences = context.getSharedPreferences(SkinContacts.PREF_NAME, Context.MODE_PRIVATE);
    }

    //获得插件路径
    public String getPluginPath() {
        if (sharedPreferences == null) return "";
        return sharedPreferences.getString(SkinContacts.KEY_PLUGIN_PATH, "");
    }

    //添加插件路径
    public void setPluginPath(String pluginPath) {
        if (sharedPreferences == null) return;
        sharedPreferences.edit().putString(SkinContacts.KEY_PLUGIN_PATH, pluginPath).apply();
    }

    //获得资源后缀
    public String getAttrSuffix() {
        if (sharedPreferences == null) return "";
        return sharedPreferences.getString(SkinContacts.KEY_PLUGIN_SUFFIX, "");
    }

    //添加资源后缀
    public void setAttrSuffix(String attrSuffix) {
        if (sharedPreferences == null) return;
        sharedPreferences.edit().putString(SkinContacts.KEY_PLUGIN_SUFFIX, attrSuffix).apply();
    }

    //获得插件的包名
    public String getPluginPackage() {
        if (sharedPreferences == null) return "";
        return sharedPreferences.getString(SkinContacts.KEY_PLUGIN_PACKAGE, "");
    }

    //添加插件的包名
    public void setPluginPackage(String pluginPackage) {
        if (sharedPreferences == null) return;
        sharedPreferences.edit().putString(SkinContacts.KEY_PLUGIN_PACKAGE, pluginPackage).apply();

    }

    //清理当前的sharedPreferences
    public boolean clear() {
        if (sharedPreferences == null) return false;
        return sharedPreferences.edit().clear().commit();
    }
}

这没啥好说的,键值对保存在app中。

3,定义换肤常量

SkinContacts类

/**
 * 皮肤常量
 */
public class SkinContacts {
   

    public static final String PREF_NAME = "skin_plugin_name";//插件工厂名
    public static final String KEY_PLUGIN_PATH = "key_plugin_path";//插件路径
    public static final String KEY_PLUGIN_PACKAGE = "key_plugin_package";//插件包名
    public static final String KEY_PLUGIN_SUFFIX = "key_plugin_suffix";//插件后缀
    public static final String ATTR_PREFIX = "skin:";//资源验证的前缀,只有带有skin的前缀才是要被修改的前缀
    public static final int SKIN_TAG = 0x5201314;//表填验证,获得当前view的所有名字
}

4,重点方法1:皮肤资源管理器

ResourceManager类

/**
 * 皮肤资源管理器
 */
public class ResourceManager {
   
    private Resources mResources;//资源对象
    private String mPluginPackageName;//插件包名
    private String mSuffix;//皮肤区别的后缀名

    //默认图片和颜色类型
    private static final String DEFTYPE_DRAWABLE = "drawable";
    private static final String DEFTYPE_COLOR = "color";

    public ResourceManager(Resources mResources, String mPluginPackageName, String mSuffix) {
        this.mResources = mResources;
        this.mPluginPackageName = mPluginPackageName;
        this.mSuffix = TextUtils.isEmpty(mSuffix) ? "" : mSuffix;
    }

    //将资源名添加后缀,用于app内部的皮肤修改
    private String appendSuffix(String name) {
        //如果设置了皮肤的后缀名,则在资源名称的
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值