Android 的 CalendarView 的 Material Design 后端端口。 目标是拥有 Material 的外观和感觉,而不是 100% 与平台的实现相同。
二、效果图1. 添加依赖:
allprojects {
repositories {
google()
mavenCentral()
maven { url 'https://jitpack.io' }
jcenter() // Warning: this repository is going to shut down soon
}
}
---------------------------------------------------------
implementation 'com.github.prolificinteractive:material-calendarview:1.6.0'
2. dialog_material_calendar.xml
3. material_calendar_decorator_selected_bg.xml
四、代码
decorators/TodayDecorator.java (今天的日期的文本特殊显示(加粗、加大字号))
public class TodayDecorator implements DayViewDecorator {
private final CalendarDay today;
private ForegroundColorSpan span;//文本颜色
public TodayDecorator(Context mContext) {
today = CalendarDay.today();
span = new ForegroundColorSpan(mContext.getResources().getColor(R.color.materialcalendar_today_border_color));
}
@Override
public boolean shouldDecorate(CalendarDay day) {
return today.equals(day);
}
@Override
public void decorate(DayViewFacade view) {
view.addSpan(span);
view.addSpan(new StyleSpan(Typeface.BOLD));
view.addSpan(new RelativeSizeSpan(1.4f));
}
}
decorators/SelectedDayDecorator.java
public class SelectedDayDecorator implements DayViewDecorator {
private CalendarDay selectedDate = null;
public SelectedDayDecorator() {
selectedDate = CalendarDay.today();
}
@Override
public boolean shouldDecorate(CalendarDay day) {
return selectedDate != null && day.equals(selectedDate) && !day.equals(CalendarDay.today());
}
@Override
public void decorate(DayViewFacade view) {
view.addSpan(new RelativeSizeSpan(1.4f));
view.addSpan(new StyleSpan(Typeface.BOLD));
}
/**
*
*/
public void setDate(Date date) {
this.selectedDate = CalendarDay.from(date);
}
}
decorators/CustomDecorator.java
public class CustomDecorator implements DayViewDecorator {
private final Drawable mDrawable;
public CustomDecorator(Context context) {
mDrawable = context.getResources().getDrawable(R.drawable.material_calendar_decorator_selected_bg);
}
@Override
public boolean shouldDecorate(CalendarDay day) {
return true;
}
@Override
public void decorate(DayViewFacade view) {
view.setSelectionDrawable(mDrawable);
}
}
MaterialCalendarDialog.java
public class MaterialCalendarDialog extends DialogFragment {
private static final String TAG = MaterialCalendarDialog.class.getSimpleName();
/**View实例*/
private View myView;
/**context实例*/
private Context mContext;
/**标记:用来代表是从哪个界面打开的这个对话框*/
private String mTag;
//年份文本
private TextView mYear;
//月日星期文本
private TextView mMonthDay;
//日历控件
private MaterialCalendarView mCalendarView;
//取消文本
private TextView mCancleBtn;
//确定文本
private TextView mOkBtn;
private Date selectedDate;//选中的日期
private final SelectedDayDecorator selectedDayDecorator = new SelectedDayDecorator();
public static MaterialCalendarDialog getInstance(Context mContext, Date selectedDate){
MaterialCalendarDialog dialog = new MaterialCalendarDialog();
dialog.mContext = mContext;
if(selectedDate == null){
Calendar calendar = Calendar.getInstance();
selectedDate = calendar.getTime();
}
dialog.selectedDate = selectedDate;
return dialog;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_NoTitleBar_Fullscreen);//全屏
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.parseColor("#80000000")));//设置背景为半透明,并且没有标题
getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);// 去掉标题栏
//设置窗体全屏
getDialog().getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
myView = inflater.inflate(R.layout.dialog_material_calendar, container, false);
return myView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
//初始化控件以及设置初始数据和监听事件
initView();
//初始化数据
initData();
//初始化监听事件
initEvent();
}
/**
* 设置宽度和高度值,以及打开的动画效果
*/
@Override
public void onStart() {
super.onStart();
//设置对话框的宽高,必须在onStart中
DisplayMetrics metrics = new DisplayMetrics();
this.getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
Window window = this.getDialog().getWindow();
window.setLayout(metrics.widthPixels, metrics.heightPixels - getStatusBarHeight(mContext));
window.setGravity(Gravity.BOTTOM);//设置在底部
//打开的动画效果--缩放+渐隐
}
/**获取状态栏的高度*/
private int getStatusBarHeight(Context context) {
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
return context.getResources().getDimensionPixelSize(resourceId);
}
/**实例化控件*/
private void initView() {
mYear = (TextView) myView.findViewById(R.id.tv_year);
mMonthDay = (TextView) myView.findViewById(R.id.tv_monthday);
mCalendarView = (MaterialCalendarView) myView.findViewById(R.id.calendarView);
mCancleBtn = (TextView) myView.findViewById(R.id.tv_cancel);
mOkBtn = (TextView) myView.findViewById(R.id.tv_ok);
}
private void initData() {
mTag = this.getTag();
Log.e(TAG, "mTag="+mTag);
parseDateToYearMonthDayWeek(selectedDate);//显示默认的日期文本
mCalendarView.setSelectedDate(selectedDate);//设置选中的日期
mCalendarView.setCurrentDate(selectedDate);//实现定位到选中日期的当月
mCalendarView.setArrowColor(Color.parseColor("#1A78EC"));//设置切换月份的箭头的颜色值【没有起作用】
//设置最小和最大日期
try {
Date minDate = DateTimeHelper.parseStringToDate("1970-01-01");
Date maxDate = DateTimeHelper.parseStringToDate("2070-01-01");
mCalendarView.state().edit()
// .setFirstDayOfWeek(Calendar.MONDAY) //设置每周开始的第一天
.setMinimumDate(minDate)
.setMaximumDate(maxDate)
// .setCalendarDisplayMode(CalendarMode.MONTHS)//设置显示模式,可以显示月的模式,也可以显示周的模式
.commit();
} catch (ParseException e) {
e.printStackTrace();
}
// mCalendarView.state().edit().setMaximumDate(maxDate).commit();
mCalendarView.addDecorators(new CustomDecorator(mContext),
selectedDayDecorator,
new TodayDecorator(mContext));
}
//初始化监听事件
private void initEvent() {
//日历控件的点击事件
mCalendarView.setOnDateChangedListener(new OnDateSelectedListener() {
@Override
public void onDateSelected(@NonNull MaterialCalendarView widget, @NonNull CalendarDay date, boolean selected) {
selectedDate = date.getDate();
parseDateToYearMonthDayWeek(selectedDate);
//刷新选中的状态
selectedDayDecorator.setDate(selectedDate);
widget.invalidateDecorators();
}
});
//取消按钮的点击事件
mCancleBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
}
});
//确定按钮的点击事件
mOkBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
if(OnokClickLitener != null){
OnokClickLitener.onOkClick(selectedDate);
}
}
});
}
/*=====================OnOkClickLitener================================*/
public interface OnOkClickLitener
{
/**确定按钮的点击事件*/
void onOkClick(Date date);
}
private OnOkClickLitener OnokClickLitener;
public void setOnOkClickLitener(OnOkClickLitener OnokClickLitener)
{
this.OnokClickLitener = OnokClickLitener;
}
/**解析日期,获取年月日星期*/
private void parseDateToYearMonthDayWeek(Date date){
//获取默认选中的日期的年月日星期的值,并赋值
Calendar calendar = Calendar.getInstance();//日历对象
calendar.setTime(date);//设置当前日期
String yearStr = calendar.get(Calendar.YEAR)+"";//获取年份
int month = calendar.get(Calendar.MONTH) + 1;//获取月份
String monthStr = month
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?