觉得有帮助的可以给个star,有问题联系 idic779@163.com QQ 290950778,有定制问题直接提issue
可以点击进去查看实现过程 纵享丝滑滑动切换的周月日历,水滴效果,丰富自定义日历样式,仿小米日历
之前开发任务中有涉及到年月日日历的切换效果,由于是需要联动,想到的方向大概有3种,要么通过处理view的touch事件,要么是通过自定义behavior去实现,要么是通过ViewDragHelper这个神器去实现,网上比较多的是通过自定义bahavior去实现,本文使用的是第三种方法,实现的是一个可高度定制自由切换的周月日历视图,提供一种思路去实现页面联动效果。
- 可以控制是否允许左右滑动,上下滑动,切换年月
- 流畅的上下周月模式切换
- 允许选择农历和普通日历
- 丰富自定义日历样式
- 设置每周的第一天
- 设置某一天不允许选中
- 基于material-calendarview 这个库实现,可以下载源码根据需求定制效果
支持grid and staggeredgrid layoutManager
gradle
allprojects {
repositories {
......
maven { url 'https://jitpack.io' }
}
}
dependencies {
......
compile 'com.github.idic779:monthweekmaterialcalendarview:1.7'
}
<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>
- 底部的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参考
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.