• 开源中国源码学习(八)——枚举类


    感觉这主页面这块还是比较复杂的,这段时间在学习这部分的源码,一遍遍的读源码,收获比较大的一部分是主页面四个Tab页面的展现形式。 
    这块儿借助了枚举类来完成相应的操作,是以前没有涉及过的,感觉很新鲜。
    
    TabHost的五个Tab初始化
    
    总体来说就是通过枚举类来列出5个Tab对应的内容页。在源码中初始化五个Tab页的代码如下所示:
    
     //初始化底部的五个Tab页
     private void initTabs() {
                //调用枚举类MainTab的values方法,获得MainTab枚举类数组
            MainTab[] tabs = MainTab.values();
    
            final int size = tabs.length;
            for (int i = 0; i < size; i++) {
                     //根据index获得具体对应的MainTab
                MainTab mainTab = tabs[i];
                //初始化每个Tab对应的图标、文字
                TabSpec tab = mTabHost.newTabSpec(getString(mainTab.getResName()));
                View indicator = LayoutInflater.from(getApplicationContext())
                        .inflate(R.layout.tab_indicator, null);
                TextView title = (TextView) indicator.findViewById(R.id.tab_title);
                Drawable drawable = this.getResources().getDrawable(
                        mainTab.getResIcon());
    
                title.setCompoundDrawablesWithIntrinsicBounds(null, drawable, null,
                        null);
                if (i == 2) {
                    indicator.setVisibility(View.INVISIBLE);
                    mTabHost.setNoTabChangedTag(getString(mainTab.getResName()));
                }
                title.setText(getString(mainTab.getResName()));
                tab.setIndicator(indicator);
                tab.setContent(new TabContentFactory() {
    
                    @Override
                    public View createTabContent(String tag) {
                        return new View(MainActivity.this);
                    }
                });
                //为TabHost添加对应的页面内容
                mTabHost.addTab(tab, mainTab.getClz(), null);
                     //如果对应的是我的界面则添加一个消息提醒的右上角图标。
                if (mainTab.equals(MainTab.ME)) {
                    View cn = indicator.findViewById(R.id.tab_mes);
                    mBvNotice = new BadgeView(MainActivity.this, cn);
                    mBvNotice.setBadgePosition(BadgeView.POSITION_TOP_RIGHT);
                    mBvNotice.setTextSize(TypedValue.COMPLEX_UNIT_SP, 10);
                    mBvNotice.setBackgroundResource(R.drawable.notification_bg);
                    mBvNotice.setGravity(Gravity.CENTER);
                }
                mTabHost.getTabWidget().getChildAt(i).setOnTouchListener(this);
            }
        }
    
    Tab页的生成方式
    
    在枚举类中来生成,代码如下:
    
    package net.oschina.app.ui;
    
    import net.oschina.app.R;
    import net.oschina.app.fragment.ExploreFragment;
    import net.oschina.app.fragment.MyInformationFragment;
    import net.oschina.app.viewpagerfragment.NewsViewPagerFragment;
    import net.oschina.app.viewpagerfragment.TweetsViewPagerFragment;
    
    public enum MainTab {
    
        //对应新闻页面
        NEWS(0, R.string.main_tab_name_news, R.drawable.tab_icon_new,
                NewsViewPagerFragment.class),
        //对应动态页面
        TWEET(1, R.string.main_tab_name_tweet, R.drawable.tab_icon_tweet,
                TweetsViewPagerFragment.class),
      //对应快速页面
        QUICK(2, R.string.main_tab_name_quick, R.drawable.tab_icon_new,
                null),
      //对应浏览页面
        EXPLORE(3, R.string.main_tab_name_explore, R.drawable.tab_icon_explore,
                ExploreFragment.class),
      //对应“我”的页面
        ME(4, R.string.main_tab_name_my, R.drawable.tab_icon_me,
                MyInformationFragment.class);
    
      //该枚举的页面index:0、1、2、3、4
        private int idx;
        //该枚举的页面的资源名字:综合、动弹、快速、发现、我
        private int resName;
        //每个枚举对应的icon
        private int resIcon;
        //每个枚举对应的Fragment的class
        private Class<?> clz;
    
       //枚举类的构造方法
        private MainTab(int idx, int resName, int resIcon, Class<?> clz) {
            this.idx = idx;
            this.resName = resName;
            this.resIcon = resIcon;
            this.clz = clz;
        }
    
        public int getIdx() {
            return idx;
        }
    
        public void setIdx(int idx) {
            this.idx = idx;
        }
    
        public int getResName() {
            return resName;
        }
    
        public void setResName(int resName) {
            this.resName = resName;
        }
    
        public int getResIcon() {
            return resIcon;
        }
    
        public void setResIcon(int resIcon) {
            this.resIcon = resIcon;
        }
    
        public Class<?> getClz() {
            return clz;
        }
    
        public void setClz(Class<?> clz) {
            this.clz = clz;
        }
    }
    
    枚举类的学习
    
    枚举类涉及到的方法
    
    ordinal()用来返回枚举值在枚举类中的顺序。
    
    compareTo ()比较两个枚举值的顺序,返回顺序之差。
    
    values(),静态方法,返回包含一个全部枚举值的数组。
    
    toString(),返回枚举常量的名称
    
    valueOf(),返回指定没弄成的枚举类型的枚举常量。
    
    Java中枚举的7中常见用法
    
    常量
    
    在JDK1.5 之前,我们定义常量都是: public static fianl…. 。现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法。
    
    public enum Color {  
      RED, GREEN, BLANK, YELLOW  
    }  
    
    switch
    
    JDK1.6之前的switch语句只支持int,char,enum类型,使用枚举,能让我们的代码可读性更强。
    
    enum Signal {  
        GREEN, YELLOW, RED  
    }  
    public class TrafficLight {  
        Signal color = Signal.RED;  
        public void change() {  
            switch (color) {  
            case RED:  
                color = Signal.GREEN;  
                break;  
            case YELLOW:  
                color = Signal.RED;  
                break;  
            case GREEN:  
                color = Signal.YELLOW;  
                break;  
            }  
        }  
    }  
    
    向枚举中添加新方法
    
    如果打算自定义自己的方法,那么必须在enum实例序列的最后添加一个分号。而且 Java 要求必须先定义 enum 实例。
    
    public enum Color {  
        RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);  
        // 成员变量  
        private String name;  
        private int index;  
        // 构造方法  
        private Color(String name, int index) {  
            this.name = name;  
            this.index = index;  
        }  
        // 普通方法  
        public static String getName(int index) {  
            for (Color c : Color.values()) {  
                if (c.getIndex() == index) {  
                    return c.name;  
                }  
            }  
            return null;  
        }  
        // get set 方法  
        public String getName() {  
            return name;  
        }  
        public void setName(String name) {  
            this.name = name;  
        }  
        public int getIndex() {  
            return index;  
        }  
        public void setIndex(int index) {  
            this.index = index;  
        }  
    }  
    
    覆盖枚举的方法
    
    下面给出一个toString()方法覆盖的例子。
    
    public enum Color {  
        RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);  
        // 成员变量  
        private String name;  
        private int index;  
        // 构造方法  
        private Color(String name, int index) {  
            this.name = name;  
            this.index = index;  
        }  
        //覆盖方法  
        @Override  
        public String toString() {  
            return this.index+"_"+this.name;  
        }  
    }  
    
    实现接口
    
    所有的枚举都继承自java.lang.Enum类。由于Java 不支持多继承,所以枚举对象不能再继承其他类。
    
    public interface Behaviour {  
        void print();  
        String getInfo();  
    }  
    public enum Color implements Behaviour{  
        RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);  
        // 成员变量  
        private String name;  
        private int index;  
        // 构造方法  
        private Color(String name, int index) {  
            this.name = name;  
            this.index = index;  
        }  
        //接口方法  
        @Override  
        public String getInfo() {  
            return this.name;  
        }  
        //接口方法  
        @Override  
        public void print() {  
            System.out.println(this.index+":"+this.name);  
        }  
    }  
    
    使用接口组织枚举
    
    public interface Food {  
        enum Coffee implements Food{  
            BLACK_COFFEE,DECAF_COFFEE,LATTE,CAPPUCCINO  
        }  
        enum Dessert implements Food{  
            FRUIT, CAKE, GELATO  
        }  
    }  
    
    关于枚举集合的使用
    
    java.util.EnumSet和java.util.EnumMap是两个枚举集合。EnumSet保证集合中的元素不重复;EnumMap中的key是enum类型,而value则可以是任意类型。关于这个两个集合的使用就不在这里赘述,可以参考JDK文档。
    
    关于枚举的实现细节和原理请参考:
    
    参考资料:《ThinkingInJava》第四版
    
    参考文章:Java 枚举7常见种用法
  • 相关阅读:
    一些浏览器的兼容和雪碧图的使用
    常用的一些样式
    Open.auth 开源项目学习(一)SSO单点登录
    一个开发人员对于职业生涯规划的感想
    从今天开始分享自己的学习经历
    mysql在海量数据时的处理方案
    Mysql分区
    su和sudo的区别
    su:authentication failure问题
    大数据处理思路
  • 原文地址:https://www.cnblogs.com/yaowen/p/5625883.html
Copyright © 2020-2023  润新知