日历选择器DatePicker

如何集成到项目

方式一 直接从maven center compile

compile 'cn.aigestudio.datepicker:DatePicker:2.2.0'

方式二 手动导入

步骤一

将DatePicker这个Module导入你的Project中

步骤二

在你Project的settings.gradle文件中增加如下内容:

include ':DatePicker'

这里要注意的是在一些gradle版本中需要以英文逗号的方式追加Module:

include ':YourMoudle',':DatePicker'

添加后当出现“sycn now”提示时点击同步即可

步骤三

在你项目的build.gradle文件的dependencies区域中添加如下内容:

compile project(':DatePicker')

如何使用

简单使用

一旦将DatePicker集成到项目后你便可以像普通控件那样使用它。

如果你需要获取DatePicker日期选择后返回的数据你需要为DatePicker设置一个OnDateSelectedListener监听器:

......
DatePicker picker = (DatePicker) findViewById(R.id.main_dp);
picker.setDate(2015, 7);
picker.setOnDateSelectedListener(new DatePicker.OnDateSelectedListener() {
    @Override
    public void onDateSelected(List<String> date) {
        String result = "";
        Iterator iterator = date.iterator();
        while (iterator.hasNext()) {
            result += iterator.next();
            if (iterator.hasNext()) {
                result += "\n";
            }
        }
        Toast.makeText(MainActivity.this, result, Toast.LENGTH_LONG).show();
    }
});
......

setDate方法允许你设置当前月历显示的年月。注意该方法必须调用,也就是说你必须为DatePicker指定一个确切年月

默认情况下DatePicker 2.0的选择模式为多选模式,你可以通过setMode方法来设置DatePicker的选择模式,该方法接受一个DPMode类型的枚举值,DatePicker 2.0支持两种选择模式:单选DPMode.SINGLE和多选DPMode.MULTIPLE,设置方式如下:

......
DatePicker picker = (DatePicker) findViewById(R.id.main_dp);
picker.setDate(2015, 7);
picker.setMode(DPMode.SINGLE);
......

在单选模式下,如果你想要获取DatePicker日期选择后返回的数据,你就不能再将DatePicker的监听设置为OnDateSelectedListener而应该设置为OnDatePickedListener:

......
DatePicker picker = (DatePicker) findViewById(R.id.main_dp);
picker.setDate(2015, 7);
picker.setMode(DPMode.SINGLE);
picker.setOnDatePickedListener(new DatePicker.OnDatePickedListener() {
    @Override
    public void onDatePicked(String date) {
        Toast.makeText(MainActivity.this, date, Toast.LENGTH_LONG).show();
    }
});
......

这里需要注意的是,你不能将DatePicker设置为多选或单选模式的情况下又设置为单选或多选,在一个实例中只能接受一种选择模式

选择后的日期将会以列表(多选模式下)或字符串(单选模式下)的形式返回,日期字符串的格式为:

yyyy-M-d

比如:2015-3-28

高级定制

DatePicker 2.0默认了一套显示机制,对于天朝月历而言,2015年的假期与补休都会被不同的背景圆颜色所标识,对于其他国家月历而言只有假期会被标识,当然,在某些情况下你还想在某些特定的日期有自己的显示标识,DatePicker 2.0在原有绘制层的基础上分割出了一个背景层,提供给用户绘制自己想要的标识物。比如你想在2015-7-1,2015-7-8,2015-7-16这三个日期上绘制一个不同的背景圆,首先你要通过DPCManager的setDecorBG方法设置一个日期列表,该列表包含了需要绘制背景标识的日期(在没有特殊说明的情况下,DatePicker 2.0中所使用到的日期格式均与上述一致):

......
List<String> tmp = new ArrayList<>();
tmp.add("2015-7-1");
tmp.add("2015-7-8");
tmp.add("2015-7-16");
DPCManager.getInstance().setDecorBG(tmp);
......

然后你就可以调用DatePicker的setDPDecor方法为DatePicker绘制装饰物背景:

......
List<String> tmp = new ArrayList<>();
tmp.add("2015-7-1");
tmp.add("2015-7-8");
tmp.add("2015-7-16");
DPCManager.getInstance().setDecorBG(tmp);

DatePicker picker = (DatePicker) findViewById(R.id.main_dp);
picker.setDate(2015, 7);
picker.setDPDecor(new DPDecor() {
    @Override
    public void drawDecorBG(Canvas canvas, Rect rect, Paint paint) {
        paint.setColor(Color.RED);
        canvas.drawCircle(rect.centerX(), rect.centerY(), rect.width() / 2F, paint);
    }
});
......

这里我们在2015-7-1,2015-7-8,2015-7-16这三个日期上绘制一个红色的背景圆:

日历选择器DatePicker

DatePicker 2.0中所提供的背景层位于日期文本的下方所有其他背景的上方,也就是说在所有的背景层中,你所自定义的背景拥有最高展示的优先级

当然,有些情况下光是绘制一个背景层往往不是不够的,DatePicker 2.0充分考虑到这一点,开放了位于前景层的五个装饰区域给用户绘制不同的装饰物,这五个装饰区域的位置大致如下:

日历选择器DatePicker

如上图所示,DatePicker 2.0开放了位于前景层的A、B、C、D、E五个区域让用于有机会在这些前景层的这些区域绘制一些装饰物,使用方法也非常简单,与绘制背景装饰物的逻辑类似,这里以分别在2015-7-5,2015-7-10这两个日期的左上和又上角绘制不同颜色形状的图形为例,首先你需要做的第一步与绘制背景装饰物一样,先调用DPCManager的相关方法初始化日期数据:

......
List<String> tmpTL = new ArrayList<>();
tmpTL.add("2015-7-5");
DPCManager.getInstance().setDecorTL(tmpTL);

List<String> tmpTR = new ArrayList<>();
tmpTR.add("2015-7-10");
DPCManager.getInstance().setDecorTR(tmpTR);
......

这里补充一点,从上面装饰区域的示例图中其实可以看到A、B、C、D、E五个区域分别表示的是左上角(Top left)、顶部(Top)、右上角(Top right)、左边(Left)、右边(Right),与之对应的设置日期数据与绘制的方法也采用不同的命名来区分,比如上面的代码中我们为左上角TL和右上角TR设置标识日期数据就分别用到了setDecorTL方法和setDecorTR方法,当然,在绘制的时候我们也需要在相应的方法中绘制:

......
List<String> tmpTL = new ArrayList<>();
tmpTL.add("2015-7-5");
DPCManager.getInstance().setDecorTL(tmpTL);

List<String> tmpTR = new ArrayList<>();
tmpTR.add("2015-7-10");
DPCManager.getInstance().setDecorTR(tmpTR);

DatePicker picker = (DatePicker) findViewById(R.id.main_dp);
picker.setDate(2015, 7);
picker.setDPDecor(new DPDecor() {
    @Override
    public void drawDecorTL(Canvas canvas, Rect rect, Paint paint) {
        paint.setColor(Color.GREEN);
        canvas.drawRect(rect, paint);
    }

    @Override
    public void drawDecorTR(Canvas canvas, Rect rect, Paint paint) {
        paint.setColor(Color.BLUE);
        canvas.drawCircle(rect.centerX(), rect.centerY(), rect.width() / 2, paint);
    }
});
picker.setOnDateSelectedListener(new DatePicker.OnDateSelectedListener() {
    @Override
    public void onDateSelected(List<String> date) {
        String result = "";
        Iterator iterator = date.iterator();
        while (iterator.hasNext()) {
            result += iterator.next();
            if (iterator.hasNext()) {
                result += "\n";
            }
        }
        Toast.makeText(MainActivity.this, result, Toast.LENGTH_LONG).show();
    }
});
......

绘制效果如下:

日历选择器DatePicker

注意!!!这里非常重要的一点是你必须在DatePicker显示前设置DPCManager中的相关数据!!!

功能扩展

DatePicker 2.0提供了三个Manager来管理控件的各项功能,其中DPCManager用于对日期数据的加载,这在上面的介绍中有所提及这里不再多说;DPLManager用于对语言环境的控制,DatePicker 2.0内置中文和英语两种语言并会根据当前系统的语言环境进行自动切换,如果你想扩展更多的语言,只需继承DPLManager并重写相关方法即可,同时你还必须在DPLManager的单例方法中增加相关逻辑以便DatePicker能识别你的语言:

    /**
     * 获取日历语言管理器
     * 
     * Get DatePicker language manager
     *
     * @return 日历语言管理器 DatePicker language manager
     */
    public static DPLManager getInstance() {
        if (null == sLanguage) {
            String locale = Locale.getDefault().getLanguage().toLowerCase();
            if (locale.equals("zh")) {
                sLanguage = new CN();
            } else {
                sLanguage = new EN();
            }
        }
        return sLanguage;
    }

最后我们还提供了一个DPTManager用于对DatePicker整体色调的控制,如果你想实现自己的主题色调,只需继承DPTheme并实现相关方法,然后再调用DPTManager的initCalendar方法传入你自定义的DPTheme对象即可。这里与DPCManager不同的是主题的初始化(也就是说DPTManager的initCalendar方法的调用)必须在DatePicker构造前完成!!!这点与DPCManager在DatePicker显示前调用不同!!!

项目github地址:https://github.com/AigeStudio/DatePicker