本篇源自于GitHub开源框架的修改:
github : MagicMashRoom/SuperCalendar
修改后我的版本:GitHub : MyCalenderTest
只需要展示本月后十二个月的日历,比如2017年9月-2018年9月。
首先进入页面就显示本月的日历2017年9月,此月不可以右滑。
如果滑动12个月后显示2018年9月,此月不可以左滑。
2017年9月-2018年9月之间的月份则可以左右滑动。
源码中左右滑动为viewpager,item数:2147483647,首次进入页面当前页为1000,意味着可以无限左右滑动,
1、首先需要设置viewpager的滑动拦截事件,重写ViewPager的dispatchTouchEvent
public class MyMonthPager extends MonthPager {
private int beforeX;
private boolean isCanScroll = true;
private int orientation = 0;//默认左右都可以滑动
// 0,左右可滑,
// -1,禁止左滑,
// 1,禁止右滑
public MyMonthPager(Context context) {
super(context);
}
public MyMonthPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (isCanScroll) {
return super.dispatchTouchEvent(ev);
} else {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
beforeX = (int) ev.getX();
break;
case MotionEvent.ACTION_MOVE:
int currentX = ((int) ev.getX());
int moveValue = currentX - beforeX;// >0右滑,<0左滑
Log.e("666", "moveValue===" + moveValue);
//向右滑或者向左滑的判断
if ((moveValue > 0 && orientation == 1) || (moveValue < 0 && orientation == (-1))) {
return false;//不可滑动
}
break;
}
return super.dispatchTouchEvent(ev);
}
}
public int getOrientation() {
return orientation;
}
public void setScrollble(int orientation, boolean isCanScroll) {
this.isCanScroll = isCanScroll;
this.orientation = orientation;
}
}
2、oncreate中设置默认:
monthPager.setScrollble(1, false);//设置默认,不可右滑
3、viewpager的onPageSelected的监听中设置:
//本年本月
CalendarDate today = new CalendarDate();
if (date.getYear() == today.getYear() && date.getMonth() == today.getMonth()) {//本月:如2017年9月
monthPager.setScrollble(1, false);//不可右滑
Log.e("666", "=== 本月===");
isCurrentMonth = true;
isNextYearCurrentMonth = false;
//下年的本月
} else if (date.getYear() == today.getYear() + 1 && date.getMonth() == today.getMonth()) {//下年的本月:如2018年9月
monthPager.setScrollble(-1, false);//不可左滑
Log.e("666", "=== 下年本月===");
isCurrentMonth = false;
isNextYearCurrentMonth = true;
//其他月
} else {
monthPager.setScrollble(0, true);//可左右滑动
Log.e("666", "=== 其他月 ===");
isCurrentMonth = false;
isNextYearCurrentMonth = false;
}
点击今日不显示顶部今日的背景框,点击其他则显示今日的背景框
效果如图:
点击今日,不显示顶部今日的背景框:
点击不是今日,显示今日的背景框:
1、oncreate中设置默认:
backToday.setBackgroundResource(0);//"字体今天"背景设置1
2、点击顶部今天的监听设置:
//回到今天
backToday.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
CalendarDate today = new CalendarDate();
calendarAdapter.notifyDataChanged(today);
textViewYearDisplay.setText(today.getYear() + "年");
textViewMonthDisplay.setText(today.getMonth() + "月");
backToday.setBackgroundResource(0);//"字体今天"背景设置2
monthPager.setScrollble(1, false);
}
});
3、点击日期的监听中设置:
@Override
public void onSelectDate(CalendarDate date) {
//"字体今天"背景设置3
CalendarDate today = new CalendarDate();
if (date.getYear() == today.getYear() && date.getMonth() == today.getMonth() && date.getDay() == today.getDay()) {//今日不需要背景
backToday.setBackgroundResource(0);
} else {//非今日都需要背景
backToday.setBackgroundResource(R.drawable.button_bg);
}
currentDate = date;
textViewYearDisplay.setText(date.getYear() + "年");
textViewMonthDisplay.setText(date.getMonth() + "月");
}
点击本月(如:2017年9月)显示的上月日期不可跳转,点击下年本月(如:2018年9月)的下月日期不可跳转
1、定义变量:
判断是否是本月(如:2017年9月,默认为true)、
判断是否是下年本月(如:2018年9月,默认为false)
并且点击回到当前月时设置 isCurrentMonth = true ; isNextYearCurrentMonth = false;//非当前月
private boolean isCurrentMonth = true;
private boolean isNextYearCurrentMonth = false;
//回到今天
backToday.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
CalendarDate today = new CalendarDate();
calendarAdapter.notifyDataChanged(today);
textViewYearDisplay.setText(today.getYear() + "年");
textViewMonthDisplay.setText(today.getMonth() + "月");
backToday.setBackgroundResource(0);//"字体今天"背景设置2
monthPager.setScrollble(1, false);
isCurrentMonth = true;//当前月
isNextYearCurrentMonth = false;//非当前月
}
});
2、viewpager的onPageSelected监听中设置:
@Override
public void onPageSelected(int position) {
mCurrentPage = position;
currentCalendars = calendarAdapter.getPagers();
if (currentCalendars.get(position % currentCalendars.size()) instanceof Calendar) {
CalendarDate date = currentCalendars.get(position % currentCalendars.size()).getSeedDate();
currentDate = date;
textViewYearDisplay.setText(date.getYear() + "年");
textViewMonthDisplay.setText(date.getMonth() + "月");
//本年本月
CalendarDate today = new CalendarDate();
if (date.getYear() == today.getYear() && date.getMonth() == today.getMonth()) {
monthPager.setScrollble(1, false);
Log.e("666", "=== 本月===");
isCurrentMonth = true;//是本月
isNextYearCurrentMonth = false;//不是下年本月
//下年的本月
} else if (date.getYear() == today.getYear() + 1 && date.getMonth() == today.getMonth()) {
monthPager.setScrollble(-1, false);
Log.e("666", "=== 下年本月===");
isCurrentMonth = false;//不是本月
isNextYearCurrentMonth = true;//是下年本月
//其他月
} else {
monthPager.setScrollble(0, true);
Log.e("666", "=== 其他月 ===");
isCurrentMonth = false;//不是本月
isNextYearCurrentMonth = false;//不是下年本月
}
}
}
3、在点击跳转月份的onSelectOtherMonth方法中,设置:
@Override
public void onSelectOtherMonth(int offset) {
Log.e("666", "=== offset ===" + offset);
//偏移量 -1表示刷新成上一个月数据 , 1表示刷新成下一个月数据
if (!isCurrentMonth && !isNextYearCurrentMonth) {//不是本月也不是下年本月可左右跳转
monthPager.selectOtherMonth(offset);
Toast.makeText(MainActivity.this, "哈哈,我是本月和下年本月之间的月份", Toast.LENGTH_SHORT).show();
} else if (isCurrentMonth && offset == 1) {//本月可跳转下个月
monthPager.selectOtherMonth(1);
Toast.makeText(MainActivity.this, "呵呵,我是本月", Toast.LENGTH_SHORT).show();
} else if (isNextYearCurrentMonth && offset == (-1)) {//下年本月可调转上个月
monthPager.selectOtherMonth(-1);
Toast.makeText(MainActivity.this, "嘻嘻,我是下年本月", Toast.LENGTH_SHORT).show();
}
}
显示的本月今日的日期一直显示白色
显示的本月非今日的日期一直显示黑色
显示的非本月日期一直显示灰色
CustomDayView类中
private void renderSelect(State state) {
//字体背景设置
if (state == State.SELECT) {//本月选中
selectedBackground.setVisibility(VISIBLE);
// dateTv.setTextColor(Color.WHITE);
} else if (state == State.NEXT_MONTH || state == State.PAST_MONTH) {//非本月日期
selectedBackground.setVisibility(GONE);
// dateTv.setTextColor(Color.parseColor("#d5d5d5"));
} else {//本月未选中
selectedBackground.setVisibility(GONE);
// dateTv.setTextColor(Color.parseColor("#111111"));
}
//字体颜色设置
if (state == State.NEXT_MONTH || state == State.PAST_MONTH) {//非本月日期
dateTv.setTextColor(Color.parseColor("#d5d5d5"));//灰色
} else {//本月日期
if (today.getYear() == day.getDate().getYear() &&
today.getMonth() == day.getDate().getMonth() &&
today.getDay() == day.getDate().getDay()) {
dateTv.setTextColor(Color.WHITE);//白色
} else {
dateTv.setTextColor(Color.parseColor("#111111"));//黑色
}
}
}
MainActivity中:
/**
* 初始化标记数据,HashMap的形式,可自定义
*
* @return void
*/
private void initMarkData() {
HashMap markData = new HashMap<>();
markData.put("2017-9-1", "1");//参数为:日期,显示样式
markData.put("2017-9-2", "0");
markData.put("2017-9-3", "1");
markData.put("2017-9-4", "0");
calendarAdapter.setMarkData(markData);
}
custom_day.xml中可设置marker的位置、大小等
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="51.4dp"
android:layout_height="45dp"
android:orientation="vertical">
<View
android:id="@+id/today_background"
android:layout_width="33dp"
android:layout_height="33dp"
android:layout_centerInParent="true"
android:background="@drawable/today_background"
android:visibility="gone" />
<View
android:id="@+id/selected_background"
android:layout_width="33dp"
android:layout_height="33dp"
android:layout_centerInParent="true"
android:background="@drawable/selected_background"
android:visibility="gone" />
<TextView
android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="19" />
<ImageView
android:id="@+id/maker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="8dp"
android:background="@drawable/view_syllabus_mark_background"
android:visibility="visible" />
RelativeLayout>
CalendarDate today = new CalendarDate();//可获取今日日期
Error:Execution failed for task ':app:processDebugManifest'.
> Manifest merger failed : uses-sdk:minSdkVersion 15 cannot be smaller than version 17 declared in library [com.github.MagicMashRoom:SuperCalendar:v1.4] C:\Users\lenovo\.android\build-cache\33a3dfeb0aa43d28d9f45fd4dd6f6c01a5a8d3a5\output\AndroidManifest.xml
Suggestion: use tools:overrideLibrary="com.ldf.mi.calendar" to force usage
原因:我项目中的minSdkVersion 15,但是导入依赖需要大于17,
android {
compileSdkVersion 25
buildToolsVersion "25.0.3"
defaultConfig {
applicationId "com.example.lenovo.mycalendertest"
minSdkVersion 15
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
解决:manifest中添加下面即可:
<uses-sdk tools:overrideLibrary="com.ldf.mi.calendar"/>
参考:【Android】Suggestion: use tools:overrideLibrary=”” to force usage