今天我们讲解枚举作为常量用法的经典案例.

需求: 有很多订单展示 , 服务端会告诉客户端每个订单的状态 , 通过status来定义每个订单的状态 , 其包括 0未开始 1:进行中 2:已完成 , 我们会根据不同的状态显示不同的文本内容 . 目前的需求就是这样的 .

需求很明确,一般我们会这么做。

在全局的常量类中定义定义3个静态常量表示状态常量:

java枚举定义多个常量_java枚举定义多个常量


接下来在strings.xml定义状态值:未开始、进行中、已完成

java枚举定义多个常量_枚举(enum)_02


最后,在代码中拿到status之后,我们会这么做:

java枚举定义多个常量_java枚举定义多个常量_03


需求很简单 , 这样就OK了.

java枚举定义多个常量_java枚举定义多个常量_04

突然有一天,产品汪找到你:Hi,我们把文本前面的颜色设置成动态的吧,不同的状态颜色不一样,你根据效果图改一下吧…”。还好这个简单,分分钟的事。

在colors.xml中,加几个色值:

java枚举定义多个常量_java枚举定义多个常量_05


然后修改switch语句,这样:

java枚举定义多个常量_java枚举定义多个常量_06

So easy,很快解决了问题!

慢慢的,随着开发的深入,你发现许多地方需要这么显示,于是就封装了一个自定义ViewGroup,一切都朝着好的方向发展。但除此之外,在其他地方,也需要判断这个状态值,以需要获取该状态下的属性,万一哪天产品汪跟你说:“我要多加一个状态,未知(UN_KONW)。服务端和iOS已经同步了,你这边赶紧吧”,意味着之前涉及状态判断的都需要找到加上,岂不傻眼了?

所以,大多数人还是会选择将这一部分写到全局的静态方法中,这样加字段、加状态再也不怕了,在对应文件中加几个常量【status、颜色、状态文本】,改一下方法就搞定!由于这块不是本文重点,就不贴代码了。

至此,我们的程序一步步完善了,一些基本的套路已经无法难倒我们了,完美!

功能基本实现了,但是回过头来想想,这样做并不优雅!一方面需求变动时我们还是需要改很多地方,另一方面我们并不能很直观的看出状态值status与状态文本、色值之间的关系,比如 0代表未开始,颜色为黄色。当然,可以向上文一样,依靠命名规范去解决这个问题。可是,在命名规范的基础上,有没有更好的办法进一步强化他们之间的关系呢?当然有!接下来,就到了今天的主题,一起来借助枚举完成这一任务。

-----------------------------------------------------枚举登场-------------------------------------------------------------

刚开始,我们可以定义一个枚举类,这么写(如果你对这一写法还不了解,可以查阅其他博文)

public enum CardStatus {

    UN_START(0, "未开始"),
    PROCESSING(1, "进行中"),
    COMPLETED(2, "已完成");

    public int mStatus;
    public String mStatusText;

    CardStatus(int status, String statusText) {
        mStatus = status;
        mStatusText = statusText;
    }

    public static CardStatus getStatusValue(int status) {
        for (CardStatus statusConstants : values()) {
            if (status == statusConstants.mStatus) {
                return statusConstants;
            }
        }
        return UN_START;
    }

}

用的时候简直不要太简单(status是从服务端获取的状态值):

CardStatus statusValue = CardStatus.getStatusValue(status);
  mStatusTv.setText(statusValue.mStatusText);

然后后来产品说加一个状态图标,你很坦然就加上了。这么写:

java枚举定义多个常量_java枚举定义多个常量_07


用的时候毫不影响:

CardStatus statusValue = CardStatus.getStatusValue(status);
   mStatusIv.setBackgroundResource(statusValue.mStatusPic);
   mStatusTv.setText(statusValue.mStatusText);

效果图:

java枚举定义多个常量_Java_08


java枚举定义多个常量_枚举(enum)_09


java枚举定义多个常量_服务端_10


重点来了,该到加未知(UN_KNOW)状态的时候了,按照上文的做法,我们要改、加的东西很多,但现在只需要加一行代码,是的,一行代码:

java枚举定义多个常量_java枚举定义多个常量_11


就是这么简单!同时,这么写的话,就不需要在 string.xml、colors.xml、常量类中加一堆值了,直接放在枚举类中很直观有木有?!当然,有时候我们需要在某个地方使用常量来判断,下图是常见的做法。现在我们把状态值写到枚举里面了,还能这么直观的用吗?答案是肯定的!

java枚举定义多个常量_Java_12

OK,关于使用枚举代替常量的分享就到这儿了。全文以故事线的形式展开,说了这么多就为这一个知识点,可见其在某些场景下还是很重要的。

最后,声明一点,我所说的使用枚举替换常量,是针对类似于“常量之间存在关联”的情况,如状态值status与状态文本、色值,此时使用枚举能大大简化我们的工作,并不是说以后所有常量都写成枚举,毕竟官方是不推荐使用枚举的:

Enums often require more than twice as much memory as static constants. You should strictly avoid using enums on Android.

但也只是尽量避免使用!所以在实际开发中,还需要根据实际使用场景去斟酌,杜绝滥用。像本文描述的场景,建议使用,战斗力翻倍!