换肤功能的实现

来源:互联网 发布:cuda linux 编辑:程序博客网 时间:2024/04/26 15:17

记得大概两年前做过一款应用,涉及的主题皮肤的更换,并不是单纯的只换背景颜色,导航栏颜色,很类似于QQ里面的皮肤更换,而是需要更换整个应用的80%图片,还有包括一部分的字体.

 我们整个ui页面和大多数app一样,一共三个模块,下面一个tabbar,上面一个导航栏,三个页面可以按底部tabbar按钮进行切换,和微信,qq布局是一样,这三个页面是常驻内存,其他页面都是通过这三个页面push过去,都是动态创建,然后返回之后销毁.

讲完UI布局之后开始设计

1.主页面设计,三个常驻内存的页面,切换的时候,viewWillApear和viewWillDisApear才能被触发,这样常驻内存的3个主界面在跳入的时候,才能实现UI的重新加载。当然这3个界面的UI处理要放到viewWillApear里来,相关的清理工作放到viewWillDisApear里实现,当在主题下载页面,下载主题包(就是图片和配置的txt),启用主题,需要发一个通知到这三个页面,通知页面换肤.

2.分页面设计,

尽量减少常驻内存的UI,实际上,只有那3个主界面时常驻的,其他的UI都不是常驻。这样在页面被打开时各个控件元素的图片都是重新被加载的。

3.主题更换方案

工程中的所有图片都要在一个映射文件(Dictionary)中维护,如下图所示,整个处理换肤的类,需要实现如下功能。

此外,在用户信息管理器中,增加当前使用的哪个主题的配置,这个配置到底有几个主题,很可能是由服务器指定的。当然,系统第一次启动时使用的是系统默认的主题,那么在获取图片数据的API中,就直接返回[UIImageimageNamed:@"dial_rec_xxx.png"],而无需操作映射文件。否则,如果用户启用了更换皮肤的话,映射文件就会被修改为当前皮肤的图片位置,这时,如果外部访问获取API时就会根据图片名称到映射文件中去找,找到图片位置的url后,通过url返回沙盒下的图片数据给App。

图片






4.主题下载方案

主题下载支持压缩、断点下载,下载后将解压的图片存放在沙盒下相应主题的目录下,如:Red目录,下载好以后以供用户启用。也就是说,每一个主题在沙盒下都有一个对应的目录进行对图片的存放。图片下载使用异步方式。


5.命名规则,这个现在在做的时候就要按照这个来命名。将来从服务器下载下来的也是这种命名

例如公用 public_xx_icon@2x.png

更多  more_xx_icon@2x.png

等等



用于换肤的类

自己写一个类,随便命名,例如叫Image类

.h文件里面 

@interface Image : UIImage

//继承后重写这个方法:根据当前使用的主题配置,和传入的图片的名称,得到图片数据,供外部使用的API

+ (UIImage *)imageNamed:(NSString *)name;

//

根据当前使用的主题配置,得到出当前使用的主题的存放目录

+ (NSString *)themePackWorkDir;


.m文件

///////////////////////////////////////////////////////////////////////////////////////////////////

/**

 继承后重写这个方法:根据当前使用的主题配置,和传入的图片的名称,得到图片数据,供外部使用的API

 */

+ (UIImage *)imageNamed:(NSString *)name

{

//    name = @"contact_list_out_btn_h@2x.png";

    UIImage *retImage=nil;

    NSString * currentThemePackID=[[UserInfoManager sharedInstancegetThemePackID];

    if ([currentThemePackID intValue]==0)//系统默认的

    {

        retImage=[UIImage imageNamed:name];

    }

    else//设置的主题

    {

        NSString *workDir=[Image themePackWorkDir];

        NSString *imagePath=[workDir stringByAppendingFormat:@"/%@",name];


        retImage = [UIImage imageWithContentsOfFile:imagePath];

        

        if (retImage==nil)//如果在沙盒下找不到,就还用系统默认的

        {

            retImage=[UIImage imageNamed:name];

        }

    }

    return retImage;

}


///////////////////////////////////////////////////////////////////////////////////////////////////

/**

 根据当前使用的主题配置,得到出当前使用的主题的存放目录

 */

+ (NSString *)themePackWorkDir

{

    NSFileManager *fileManager = [NSFileManager defaultManager];

    NSString *documentsDirectory = applicationDocumentsDirectory();

    [fileManager changeCurrentDirectoryPath:[documentsDirectory stringByExpandingTildeInPath]];

    

    //根据当前使用的主题配置构造目录名称

    NSString * currentThemePackID = [[UserInfoManager sharedInstancegetThemePackID];

    NSString *dirName=[NSString stringWithFormat:@"ThemePack_%@",currentThemePackID];

    

    NSString *createPath = [NSString stringWithFormat:@"%@/%@", documentsDirectory,dirName];

    

    return createPath;

}


上面是取的过程,还有下载的方法就不写了,下载之后把图片存入沙盒响应位置。


0 0