MaterailDesign风格的日历,MaterailCalendarView

来源:互联网 发布:淘宝店铺怎么改折扣价 编辑:程序博客网 时间:2024/05/16 08:28

   日历控件有很多,但是如果要实现在日历上标注文字或者图片,该如何实现呢,小菜鸟一枚,下面写写我在项目里用到的一个控件--MaterialCalendarView, 基于MaterailDesign风格De日历,据说最早是由外国人写的,然后开源出来了,之所以会选中这个是他可以较方便的在日历上添加标记,而且MaterailDesign风格的很受大家好评,做项目的时候网上找了好些资料,也找了发过类似帖子的大神支援。好了下面是我的项目的demo跟效果图


这个是我项目中一个模块的截图,下面那部分日历就是效果图啦。

1.布局文件

<com.prolificinteractive.materialcalendarview.MaterialCalendarView            xmlns:app="http://schemas.android.com/apk/res-auto"            android:id="@+id/calendarView"            android:layout_width="match_parent"            android:layout_height="wrap_content"            app:mcv_tileSize="45dp"            app:mcv_dateTextAppearance="@style/dateTextAppeararent"            app:mcv_weekDayTextAppearance="@style/monthTextAppeararent"            app:mcv_headerTextAppearance="@style/headerTextAppeararent"            app:mcv_weekDayLabels="@array/custom_myweekdays"            app:mcv_monthLabels="@array/custom_mymonths"            android:layout_alignParentTop="true"            android:layout_alignParentLeft="true"            android:layout_alignParentStart="true" />

可以以添加类库的方式导入,但是最好是以导入类库的方式导入AS,这样有了源代码你就可以根据你自己的需要更改UI或者源代码了,在这里就不提供github的第三方库下载地址了,直接去github上搜MaterialCalendarView就有了。

仅提供那两个array/custom_myweekdays 和 array/custom_mymonths写在Strings.xml里,剩下的在类库里都有了

<string-array name="custom_myweekdays">        <item>日</item>        <item>一</item>        <item>二</item>        <item>三</item>        <item>四</item>        <item>五</item>        <item>六</item>    </string-array>    <string-array name="custom_mymonths">        <item>一月</item>        <item>二月</item>        <item>三月</item>        <item>四月</item>        <item>五月</item>        <item>六月</item>        <item>七月</item>        <item>八月</item>        <item>九月</item>        <item>十月</item>        <item>十一月</item>        <item>十二月</item>    </string-array>
2.接下来是Activity
<span style="font-size:14px;">    private MaterialCalendarView calendarView;    private Calendar calendar;    private OneDayDecorator oneDayDecorator= new OneDayDecorator();</span>
<pre name="code" class="java">@Override    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {            view = inflater.inflate(R.layout.orders_everyday_frag, container, false);            calendarView= (MaterialCalendarView)  view.findViewById(R.id.calendarView);            calendarView.setOnDateChangedListener(this);            calendarView.setOnMonthChangedListener(this);            calendar = Calendar.getInstance();            calendarView.setFirstDayOfWeek(calendar.SUNDAY);//设置一周起始日            calendarView.setSelectedDate(calendar.getTime());//当日选中            //系统当前日期的颜色            calendarView.addDecorators(new MyBackgroundDecorator(getActivity(), R.drawable.my_selector_orange,                    CalendarDay.from(calendar.getTime())));            //选中日期的颜色            calendarView.addDecorators(new MySelectorDecorator(getActivity(), R.drawable.my_selector_blue),                    oneDayDecorator);
//在日期上添加标记或者图片,需要用到实体类-->EventDecorator.class
list.add(new EventDecorator(getContext(),new int[]{1,orderSchedule.getServiceOrderCount() ,orderSchedule.getNewOrderCount()},strTranCalendar(orderSchedule.getWorkDate())));
           //setData(systemTime);更新ui        return view;    }
public CalendarDay strTranCalendar(String str){        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");        try {            Date date = dateFormat.parse(str);            calendar.setTime(date);            CalendarDay calendarDay = CalendarDay.from(calendar);            return calendarDay;        } catch (ParseException e) {            e.printStackTrace();return null;        }    }
//这个方法是,选中某个日期以后执行的方法,注意date的格式需要根据自己的需要处理一下
@Override    public void onDateSelected(@NonNull MaterialCalendarView widget, @NonNull CalendarDay date, boolean selected) {
        if (selected){            String substring = date.toString().substring(0, date.toString().length() - 1);            String[] split = substring.split("[{]");//特殊字符,需要转义2015-0-8            //....此处省略部分代码        }    }
//这个方法是,当左右滑动切换月份时,执行的方法
@Override    public void onMonthChanged(MaterialCalendarView widget, CalendarDay date) {        String s = DateFormatUtils.getFormatDate(date, true);//滑动后显示的月份        String curMonth = systemTime.substring(0, 7);//当前月:2015-02    }

除此之外,你还需要这几个类


其中MypointSpan是绘图的核心代码,其他几个类是类库里本身就有的,如果有需要可以在自定义一下,下面讲一下MyPointSpan.class:
public class MyPointSpan implements LineBackgroundSpan {    private Context context;    public static final float DEFAULT_RADIUS = 3;    private final float radius;    //预先定义好的颜色    private final int[] color=new int[]{1,2,3,4};    //接收过来的数据    private final  int[] data;    public MyPointSpan() {        this.radius = DEFAULT_RADIUS;        this.data = null;    }    public MyPointSpan(int[] color) {        this.radius = DEFAULT_RADIUS;        this.data = color;    }    public MyPointSpan(float radius) {        this.radius = radius;        this.data = null;    }    public MyPointSpan(Context context,float radius, int[] data) {        this.context=context;        this.radius = radius;        this.data = data;    }    @Override    public void drawBackground(            Canvas canvas, Paint paint,            int left, int right, int top, int baseline, int bottom,            CharSequence charSequence,            int start, int end, int lineNum    ) {        Resources res = context.getResources();        float common_font_sw320dp_of_10 = res.getDimension(R.dimen.common_font_sw320dp_of_10);//引用dimen文件,方便屏幕适配        int oldColor = paint.getColor();        //新加        float oldTextSize = paint.getTextSize();        paint.setTextAlign(Paint.Align.LEFT);        if(data.length!= 0&&!data.equals(null)) {            String text1;            String text2;            //清除画布            /*paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));            canvas.drawPaint(paint);            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));*/            switch (data[0]){                case 1:                    //当前日期及其当前日期之后的---区分显示--1<span style="white-space:pre"></span>      //服务中订单                    paint.setColor(getColor(color[0]));                                     paint.setTextSize(common_font_sw320dp_of_10);                    canvas.drawText(data[2] + "/", (left + right) / 4 - radius, bottom + top + radius + 12, paint);                    //新增订单                    paint.setColor(getColor(color[2]));                                       paint.setTextSize(common_font_sw320dp_of_10);                         canvas.drawText(data[1]+"", (left + right) / 2+ radius, bottom+top + radius+12, paint);                    paint.setTextSize(oldTextSize);                    paint.setColor(oldColor);                    paint.setTextAlign(Paint.Align.LEFT);                    break;            }        }        paint.setColor(oldColor);    }    public int getColor(int colorNum){        int circleColor=0;        switch (colorNum){            case 1:                int i = Color.parseColor("#fc7c0f");                circleColor=i;break;   //闲            case 2:circleColor= Color.GRAY;break;   //过去的日期显示灰色            case 3:                int j=Color.parseColor("#1eb9cf");                circleColor=j;break;     //忙            case 4:circleColor=Color.BLACK;                break;   //分割线        }        return circleColor;    }}
}
</pre><br /><pre name="code" class="java">当需要在画布上重新绘制标记的时候,想到的有两种方式:一是清除画布,但是有个很致命的缺陷就是,画布的背景色会变成黑色,试了好多种方法都没有效果
清除画布的代码:

            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));            canvas.drawPaint(paint);            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
</pre><pre name="code" class="java">第二种方式是:设置画笔的背景色background是白色,实验证明,确实有效果,但是别忘了,日历上当前日期是有圆形的背景图的,这个background会覆盖掉他。。。
最好不得已,只能让他的生命周期重新走一遍,然后重新绘制,在这里征求大家的心得,有没有更好的方式!
</pre><pre name="code" class="java">小菜鸟一枚,具体的代码剖析还请看-->http://blog.csdn.net/miss_qz14/article/details/50014617 感谢大神的帮助~



0 0
原创粉丝点击