CalendarPickerView 源码导读

本文详细解析了开源日历控件TimesSquare的结构与实现原理,包括其项目托管地址、使用方法及核心类MonthAdapter和MonthView的工作流程。通过分析MonthAdapter的getView方法和MonthView的create方法,读者可以深入了解日期与布局的对应机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CalendarPickerView  源码解析

项目相关
TimesSquare 是一个开源的日历控件。
其项目托管地址是: https://github.com/square/android-times-square


先看一下程序 Sample 运行截图:

libs 的程序结构如下:

很简单,基本上从命名上就可以区分每个类的作用。下面我用一张图来帮大家梳理一下这些类的作用:


上面的图片中我们可以看出 CalendarPickerView ListView 的子类,那么就一定会有一个 Adapter 用来为它适配数据,我们就先从这个适配器说起—— MonthAdapter 

  1. private class MonthAdapter extends BaseAdapter {
  2.                 private final LayoutInflater inflater;
  3.                 ... ...

  4.                 @Override
  5.                 public View getView(int position, View convertView, ViewGroup parent) {
  6.                         MonthView monthView = (MonthView) convertView;
  7.                         if (monthView == null) {
  8.                                 monthView = MonthView.create(parent, inflater, weekdayNameFormat,
  9.                                                 listener, today);
  10.                         }
  11.                         monthView.init(months.get(position), cells.get(position));
  12.                         return monthView;
  13.                 }
  14. }
复制代码



正如上图所示 getView 返回的视图就是 MonthView 。下面我们看一下 MonthView create() 方法 :

  1. public static MonthView create(ViewGroup parent, LayoutInflater inflater,
  2.                         DateFormat weekdayNameFormat, Listener listener, Calendar today) {
  3.                 final MonthView view = (MonthView) inflater.inflate(R.layout.month, parent,
  4.                                 false);

  5.                 final int originalDayOfWeek = today.get(Calendar.DAY_OF_WEEK);

  6.                 //========
  7.                 // 配置grid header,比如:周一、周日这些文字
  8.                 //========
  9.                 int firstDayOfWeek = today.getFirstDayOfWeek();
  10.                 final CalendarRowView headerRow = (CalendarRowView) view.grid.getChildAt(0);
  11.                 for (int offset = 0; offset < 7; offset++) {
  12.                         today.set(Calendar.DAY_OF_WEEK, firstDayOfWeek + offset);
  13.                         final TextView textView = (TextView) headerRow.getChildAt(offset);
  14.                         textView.setText(weekdayNameFormat.format(today.getTime()));
  15.                 }
  16.                 ... ...
  17.         }
复制代码


create 方法里面只是配置了 grid header 的文字,并没有把相应的日期对应到布局上去,那么是在什么地方真正负责日期与布局的对应呢?在上面 CalendarPickerView 的适配器的 getView 方法中除了调用 MonthView create 方法创建了 MonthView  对象,还调用了 init 方法,我们来看一看这个方法:


  1. public void init(MonthDescriptor month, List<List<MonthCellDescriptor>> cells) {
  2.         ... ...
  3.                 final int numRows = cells.size();
  4.                 grid.setNumRows(numRows);
  5.                 for (int i = 0; i < 6; i++) {//at most 5 rows per month
  6.                         CalendarRowView weekRow = (CalendarRowView) grid.getChildAt(i + 1);
  7.                         weekRow.setListener(listener);
  8.                         if (i < numRows) {
  9.                                 weekRow.setVisibility(VISIBLE);
  10.                                 List<MonthCellDescriptor> week = cells.get(i);
  11.                                 for (int c = 0; c < week.size(); c++) {
  12.                                         MonthCellDescriptor cell = week.get(c);
  13.                                         CalendarCellView cellView = (CalendarCellView) weekRow.getChildAt(c);

  14.                                         cellView.setText(Integer.toString(cell.getValue()));
  15.                                         ... ...
  16.                                 }
  17.                         } else {
  18.                                 weekRow.setVisibility(GONE);
  19.                         }
  20.                 }
  21.                 
  22.         }
复制代码


果然这里就是日期与布局绑定的地方。这里 cells 是一个 List<List<MonthCellDescriptor>> 类型的数据,其中 MonthCellDescriptor 这个就是一个对每月中的每一天进行描述的实体类, cells 表示一整个月的日期(为了填满这个表格我们还会显示上个月和下个月的日期),而 cells 列表中的每一项恰好是一个星期的日期。这样我们就可以把日期绑定到 CalendarCellView  这个最小的 TextView 显示日期了。

至此我们就简单的了解一下 TimesSquare 源码结构。本套开源框架实现起来并不复杂,很容易理解,只要细心阅读大家都可以读懂,也可以在此基础上开发满足自己需求的控件。

最后提供一下最近下载的项目文件,建议大家还是项目托管处下载最新源码。
 android-times-square-master.zip (242.91 KB, 下载次数: 186)

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值