实现可滑动的日历
这是简单的效果,可以滑动,是用的viewpager和自定义view实现的
首先是viewpager的代码,其实和平常的使用时一样的
viewPager = (ViewPager) findViewById(R.id.view_pager).
pagerAdapter = new CalendarPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(pagerAdapter);
viewPager.addOnPageChangeListener(this);
// 获取当天的日期所对应的position
viewPager.setCurrentItem(DateTimeUtils.getTodayMonthIndex());
重要的是fragment的创建,通过计算年份的偏移给出position
public class CalendarPagerAdapter extends FragmentStatePagerAdapter {
public CalendarPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
return CalendarPagerFragment.create(position);
}
@Override
public int getCount() {
// 计算一共有多少的position
int years = DateTimeUtils.getMaxYear() - DateTimeUtils.getMinYear();
return years * 12;
}
}
public class CalendarPagerFragment extends Fragment {
public static final String MONTH_INDEX = "month_index";
private int monthIndex;
private MonthDateView monthDateView;
public static CalendarPagerFragment create(int monthIndex) {
CalendarPagerFragment fragment = new CalendarPagerFragment();
Bundle bundle = new Bundle();
bundle.putInt(MONTH_INDEX, monthIndex);
fragment.setArguments(bundle);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
monthIndex = getArguments().getInt(MONTH_INDEX);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ViewGroup view = (ViewGroup) inflater.inflate(R.layout.view_calendar, null);
// 动态添加自定义的日历界面
monthDateView = new MonthDateView(getActivity(), monthIndex);
monthDateView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
view.addView(monthDateView);
monthDateView.invalidate();
return view;
}
}
然后是自定义的日历代码:
// 获取view的宽高,用于计算显示的坐标和距离
mDisplayMetrics = getResources().getDisplayMetrics();
Calendar calendar = Calendar.getInstance();
// 初始化画笔
mPaint = new Paint();
mPaint.setAntiAlias(true);
// 计算当前的年和月
mSelYear = DateTimeUtils.getMinYear() + (monthIndex / 12);
mSelMonth = monthIndex % 12;
@Override
protected void onDraw(Canvas canvas) {
initSize();
daysString = new int[6][7];
String dayString;
// 获取全部的天数
int mMonthDays = DateUtils.getMonthDays(mSelYear, mSelMonth);
// 月份第一天是周几
int weekNumber = DateUtils.getFirstDayWeek(mSelYear, mSelMonth);
Log.d("DateView", "DateView:" + mSelMonth + "月1号周" + weekNumber);
for (int day = 0; day < mMonthDays; day++) {
dayString = (day + 1) + "";
// 列
int column = (day + weekNumber - 1) % 7;
// 行
int row = (day + weekNumber - 1) / 7;
// 根据行,列进行赋值
daysString[row][column] = day + 1;
if (dayString.equals(mSelDay + "")) {
// 在这里可以绘制选中日期的背景色
// 记录第几行,即第几周
weekRow = row + 1;
sendMessage();
}
// 绘制横线
mPaint.setColor(mLineColor);
canvas.drawLine(0, mRowSize * (row + 1), getWidth(), mRowSize * (row + 1), mPaint);
// 绘制事务圆形标志,就是字右上角显示的事务个数
int count = PrefUtils.getInt(getDateString(day + 1), 0);
if (count != 0) {
drawCircle(row, column, day + 1, count, canvas);
}
mPaint.setTextSize(context.getResources().getDimension(R.dimen.content_text_size));
// 计算显示字体的坐标,ascent()、descent()两个函数的意思可以自行查找
int startX = (int) (mColumnSize * column + (mColumnSize - mPaint
.measureText(dayString)) / 2);
int startY = (int) (mRowSize * row + mRowSize / 2 - (mPaint
.ascent() + mPaint.descent()) / 2);
// 绘制日期
if (dayString.equals(mCurrDay + "")
&& mCurrMonth == mSelMonth) {
// 正常月,选中其他日期,则今日为红色
int startRecX = mColumnSize * column;
int startRecY = mRowSize * row;
mPaint.setColor(mSelectBGColor);
canvas.drawCircle(startRecX + mColumnSize / 2, startRecY + mRowSize / 2,
context.getResources().getDimension(R.dimen.alarm_click_bg_margin), mPaint);
mPaint.setColor(mSelectDayColor);
} else if (column == 0 || column == 6) {
// 周六日的颜色
mPaint.setColor(mWeekendColor);
} else {
mPaint.setColor(mDayColor);
}
canvas.drawText(dayString, startX, startY, mPaint);
}
}