更新于 2017/4/27:
由于 Google 不建议我们在 Android 开发中使用枚举,所以为了避免大家盲目使用枚举,我更新了一篇关于常量、注解以及枚举使用场景的 新文章。
如果你了解枚举的使用,则可以直接看新文章;如果你不是很了解枚举的使用,那么建议看完本文再继续看新的文章:
《优先使用注解,慎用枚举》
今天的话题是枚举,内容很基础,不妨以故事情节展开,最后引出使用枚举的好处。
需求:有一个任务(Task),服务端定义了一个int status来标记任务的状态,包括 未开始、进行中、已完成 这三个状态,分别用 0、1、2 来标记。我们拿到这个status之后,需要根据状态的不同,显示不同的文本(需求仍在挖掘中)。
需求很明确,一般我们会这么做。
在全局的常量类中定义定义3个静态常量表示状态常量:
接下来在strings.xml定义状态值:未开始、进行中、已完成
最后,在代码中拿到status之后,我们会这么做:
这样写,所有的状态和状态值都统一了,规范的很,效果也不错,毫无违和感!
突然有一天,产品汪找到你:Hi,我们把文本前面的颜色设置成动态的吧,不同的状态颜色不一样,你根据效果图改一下吧…”。还好这个简单,分分钟的事。
在colors.xml中,加几个色值:
然后修改switch语句,这样:
So easy,很快解决了问题!
慢慢的,随着开发的深入,你发现许多地方需要这么显示,于是就封装了一个自定义ViewGroup,一切都朝着好的方向发展。但除此之外,在其他地方,也需要判断这个状态值,以需要获取该状态下的属性,万一哪天产品汪跟你说:“我要多加一个状态,未知(UN_KONW)。服务端和iOS已经同步了,你这边赶紧吧”,意味着之前涉及状态判断的都需要找到加上,岂不傻眼了?
所以,大多数人还是会选择将这一部分写到全局的静态方法中,这样加字段、加状态再也不怕了,在对应文件中加几个常量【status、颜色、状态文本】,改一下方法就搞定!由于这块不是本文重点,就不贴代码了。
至此,我们的程序一步步完善了,一些基本的套路已经无法难倒我们了,完美!
功能基本实现了,但是回过头来想想,这样做并不优雅!一方面需求变动时我们还是需要改很多地方,另一方面我们并不能很直观的看出状态值status与状态文本、色值之间的关系,比如 0代表未开始,颜色为黄色。当然,可以向上文一样,依靠命名规范去解决这个问题。可是,在命名规范的基础上,有没有更好的办法进一步强化他们之间的关系呢?当然有!接下来,就到了今天的主题,一起来借助枚举完成这一任务。
-----------------枚举登场-----------------------------
刚开始,我们可以定义一个枚举类,这么写(如果你对这一写法还不了解,可以查阅其他博文):
用的时候简直不要太简单(status是从服务端获取的状态值):
然后后来产品说加一个色值,你很坦然就加上了。这么写:
用的时候毫不影响:
重点来了,该到加未知(UN_KNOW)状态的时候了,按照上文的做法,我们要改、加的东西很多,但现在只需要加一行代码,是的,一行代码:
就是这么简单!同时,这么写的话,就不需要在 string.xml、colors.xml、常量类中加一堆值了,直接放在枚举类中很直观有木有?!
当然,有时候我们需要在某个地方使用常量来判断,下图是常见的做法。现在我们把状态值写到枚举里面了,还能这么直观的用吗?答案是肯定的!
OK,关于使用枚举代替常量的分享就到这儿了。全文以故事线的形式展开,说了这么多就为这一个知识点,可见其在某些场景下还是很重要的。
最后,声明一点,我所说的使用枚举替换常量,是针对类似于“常量之间存在关联”的情况,如状态值status与状态文本、色值,此时使用枚举能大大简化我们的工作,并不是说以后所有常量都写成枚举,毕竟官方是不推荐使用枚举的:
Enums often require more than twice as much memory as static constants. You should strictly avoid using enums on Android.
但也只是尽量避免使用!所以在实际开发中,还需要根据实际使用场景去斟酌,杜绝滥用。像本文描述的场景,建议使用,战斗力翻倍!