monthweekmaterialcalendarview
简介:纵享丝滑滑动切换的周月日历,可流畅滑动高度定制,仿小米日历,基于 material-calendarview (Android 官方的 CalendarView)实现,简洁高效
之前开发任务中有涉及到年月日日历的切换效果,由于是需要联动,想到的方向大概有 3 种,要么通过处理 view 的 touch 事件,要么是通过自定义 behavior 去实现,要么是通过 ViewDragHelper 这个神器去实现,网上比较多的是通过自定义 bahavior 去实现,本文使用的是第三种方法,实现的是一个可高度定制自由切换的周月日历视图,提供一种思路去实现页面联动效果。
features
- 可以控制是否允许左右滑动,上下滑动,切换年月
- 流畅的上下周月模式切换
- 允许选择农历和普通日历
- 丰富自定义日历样式
- 设置每周的第一天
- 设置某一天不允许选中
- 基于 material-calendarview 这个库实现,可以下载源码根据需求定制效果 更新日志
V1.7
Usages
step 1 : 添加依赖
gradle
allprojects {
repositories {
......
maven { url 'https://jitpack.io' }
}
}
dependencies {
......
compile 'com.github.idic779:monthweekmaterialcalendarview:1.7'
}
step 2: 添加布局
<com.amy.monthweek.materialcalendarview.MonthWeekMaterialCalendarView
android:id="@+id/slidelayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/linearlayout">
<com.prolificinteractive.materialcalendarview.MaterialCalendarView
android:id="@+id/calendarView_month_mode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:mcv_calendarMode="month"
app:mcv_showOtherDates="other_months"
app:mcv_showWeekView="false" />
<com.prolificinteractive.materialcalendarview.MaterialCalendarView
android:id="@+id/calendarView_week_mode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:visibility="invisible"
app:mcv_calendarMode="week"
app:mcv_showTopBar="false"
app:mcv_showWeekView="false" />
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:orientation="vertical" />
<LinearLayout
android:id="@+id/weekview_top"
android:layout_width="match_parent"
android:layout_height="44dp"
android:background="@color/colorPrimary"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="周日" />
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="周一" />
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="周二" />
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="周三" />
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="周四" />
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="周五" />
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="周六" />
</LinearLayout>
</com.amy.monthweek.materialcalendarview.MonthWeekMaterialCalendarView>
step 3: 如何使用
- 底部的 recyclerView 的 layoutManager 要实现 ILayoutManager 接口,设置是否允许上下滑动, 例如示例中的CustomLinearLayoutManager.java
设置当前日期,日历才会滚动到对应日期
monthWeekMaterialCalendarView.setCurrentDate(selectedDate);
设置选中日期
monthWeekMaterialCalendarView.setSelectedDate(selectedDate)
添加日历的样式,例如红点 或者自定义图案
monthWeekMaterialCalendarView.addDecorator(new EventDecorator(Color.RED, dates))
移除日历样式
monthWeekMaterialCalendarView.removeDecorators();
设置当前的模式
monthWeekMaterialCalendarView.setMode(MonthWeekMaterialCalendarView.Mode.MONTH)
跳转到上一个月
monthWeekMaterialCalendarView.goToPrevious();
跳转到下个月
monthWeekMaterialCalendarView.goToNext();
设置是否允许竖直拖动,默认是允许拖动切换周月模式
monthWeekMaterialCalendarView.setCanDrag
设置是否允许左右滑动
monthWeekMaterialCalendarView.setPagingEnabled
添加选中日期、模式改变 或者月份改变的回调
monthWeekMaterialCalendarView.state().edit()
//设置最大最小日期
.setMinimumDate(new CalendarDay(2017,1,1))
.setMaximumDate(new CalendarDay(2018,3,1))
.setSlideModeChangeListener(new MonthWeekMaterialCalendarView.SlideModeChangeListener() {
@Override
public void modeChange(MonthWeekMaterialCalendarView.Mode mode) {
}
}).setSlideDateSelectedlistener(new MonthWeekMaterialCalendarView.SlideDateSelectedlistener() {
@Override
public void onDateSelected(@NonNull MaterialCalendarView widget, @NonNull CalendarDay date, boolean selected) {
}
}).setSlideOnMonthChangedListener(new MonthWeekMaterialCalendarView.SlideOnMonthChangedListener() {
@Override
public void onMonthChanged(MaterialCalendarView widget, CalendarDay date) {
}
}).commit();
设置选中颜色
monthWeekMaterialCalendarView.setSelectionColor
因为基于 MaterialCalendarView 的周和月视图组成的,所以可以在 XML 中设置选中颜色,字体样式等等
<com.prolificinteractive.materialcalendarview.MaterialCalendarView
android:id="@+id/calendarView_month_mode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:mcv_selectionColor="@color/colorPrimary"
app:mcv_dateTextAppearance="@style/TextAppearance.MaterialCalendarWidget.Date"
app:mcv_calendarMode="month"
app:mcv_showOtherDates="defaults|other_months"
app:mcv_showWeekView="false" />
<com.prolificinteractive.materialcalendarview.MaterialCalendarView
android:id="@+id/calendarView_week_mode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:visibility="invisible"
app:mcv_selectionColor="@color/colorPrimary"
app:mcv_dateTextAppearance="@style/TextAppearance.MaterialCalendarWidget.Date"
app:mcv_calendarMode="week"
app:mcv_showTopBar="false"
app:mcv_showWeekView="false" />
定制用法
如果你想给单独的日期视图设置一些样式的话,例如周末右上角有个图标这样子的需求之类的话,你可以写一个类继承自 DayViewDecorator
public class RemindDecorator implements DayViewDecorator {
private final Calendar calendar = Calendar.getInstance();
private Context context;
public RemindDecorator(Context context) {
this.context=context;
}
@Override
public boolean shouldDecorate(CalendarDay day) {
day.copyTo(calendar);
int weekDay = calendar.get(Calendar.DAY_OF_WEEK);
return weekDay == Calendar.SATURDAY || weekDay == Calendar.SUNDAY;
}
@Override
public void decorate(DayViewFacade view) {
view.addSpan(new RestSpan(context));
}
}
- shouldDecorate()这个方法是判断是否需要添加 Decorator 的条件
- decorate()这个方法可以对显示样式做一些操作
DayViewFacade 可以通过 setSelectionDrawable(),setBackgroundDrawable(),addSpan()设置样式,尤其是 addSpan 的方法,因为你传进去的是一个 span,所以你可以在里面做很多自定义样式的操作,例如RestSpan.java周末右上角加个图标。
还可以怎么用
接下来说下你可以怎么去定制?如果你想替换项目中的月和周视图的话,很简单,
只需要你自己的周月视图必须有一个方法获得单行日历的高度(例如我的库中的 MaterialCalendarView.getItemHeight() ),
然后把这个月视图和周视图,分别在 MonthWeekMaterialCalendarView 里面按照顺序放到对应位置即可。
然后再 setListener()里面设置相关的回调处理,例如日期选中或者月份切换的回调等。
更多的使用方法可以下载 demo 参考
License
Copyright 2018 amy
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.