android c混合编程 pdf,用c/c++混合编程方式为ios/android实现一个自绘日期选择控件(一C)...

3) 月历操作函数:

/*

blf: calendar dayBeginIdx 和 dayCount图示

0 1 2 3 4 5 6 week section

---------------------------

1 rowIdx = 0

---------------------------

---------------------------

2 3 4 5 6 7 8 rowIdx = 1

---------------------------

---------------------------

9 10 11 12 13 14 15 rowIdx = 2

---------------------------

---------------------------

16 17 18 19 20 21 22 rowIdx = 3

---------------------------

---------------------------

23 24 24 25 26 27 28 rowIdx = 4

---------------------------

---------------------------

30 31 rowIdx = 5

---------------------------

*/

void calendar_set_year_month(SCalendar* calendar,int year,int month)

{

assert(calendar);

//if(calendar->date.year != year calendar->date.month != month)

{

calendar->date.year = year;

calendar->date.month = month;

//每个day设置为1号

calendar->date.day = 1;

//blf:

//参考上面图示,dayBeginIdx获得的是某个月1号相对日期区块中的索引,例如本例中1号索引为6

//而dayCount表示当前月的天数

//这样通过偏移与长度,我们可以很容易进行某些重要操作

//例如在碰撞检测某个cell是否被点中时,可以跳过没有日期的cell

//在绘图时检测某个cell是否找范围之外,如果之外就用灰色现实等等

//通过偏移量和count,进行范围判断

calendar->dayBeginIdx = date_get_week(&calendar->date);

calendar->dayCount = date_get_month_of_day(calendar->date.year, calendar->date.month);

}

}

void calendar_get_year_month(SCalendar* calendar,int* year,int* month)

{

assert(calendar);

if(year)

*year = calendar->date.year;

if(month)

*month = calendar->date.month;

}

/*

blf: 初始化一个月历结构,填充所有成员变量的数据

*/

void calendar_init(SCalendar* calendar,CGSize ownerSize,float yearMonthHeight,float weekHeight)

{

assert(calendar && calendar);

//memset(calendar, 0, sizeof(SCalendar));

calendar->size = ownerSize;

calendar->yearMonthSectionHeight = yearMonthHeight;

calendar->weekSectionHegiht = weekHeight;

//blf:daySectionHeight是计算出来的

calendar->daySectionHeight = ownerSize.height - yearMonthHeight - weekHeight;

//blf:错误检测,简单期间,全部使用assert在debug时候进行中断

assert(calendar->daySectionHeight > 0);

//blf:初始化时显示本地当前的年月日

//date_get_now(&calendar->date);

calendar_set_year_month(calendar, calendar->date.year, calendar->date.month);

}

/*

blf: 计算出年月区块的rect

*/

void calendar_get_year_month_section_rect(const SCalendar* calendar,CGRect* rect)

{

assert(rect);

memset(rect,0,sizeof(CGRect));

rect->size.width = calendar->size.width;

rect->size.height = calendar->yearMonthSectionHeight;

}

/*

blf: 计算出星期区块的rect

*/

void calendar_get_week_section_rect(const SCalendar* calendar,CGRect* rect)

{

assert(rect);

memset(rect,0,sizeof(CGRect));

rect->origin.y = calendar->yearMonthSectionHeight;

rect->size.width = calendar->size.width;

rect->size.height = calendar->weekSectionHegiht;

}

/*

blf: 计算出年日期区块的rect

*/

void calendar_get_day_section_rect(const SCalendar* calendar,CGRect* rect)

{

assert(calendar && rect);

memset(rect,0,sizeof(CGRect));

rect->origin.y = calendar->yearMonthSectionHeight + calendar->weekSectionHegiht;

rect->size.width = calendar->size.width;

rect->size.height = calendar->daySectionHeight;

}

/*

blf: 上面计算出来的是三大整体的区块(section)

下面计算出来的都是某个大区快中的子区(cell)

*/

/*

blf:

获取星期区块中每个索引指向的子区rect位置与尺寸

输出数据在rect参数中

---------------------------

0 1 2 3 4 5 6

---------------------------

idx = 0时表示星期日

用于绘图

*/

void calendar_get_week_cell_rect(const SCalendar* calendar,CGRect* rect,int idx)

{

assert(calendar && rect && idx >= 0 && idx < 7);

//获取星期区块

calendar_get_week_section_rect(calendar, rect);

//计算出cell的宽度

float cellWidth = rect->size.width / 7.0F;

//计算出x偏移量

rect->origin.x = cellWidth * idx;

rect->size.width = cellWidth;

}

/*

blf:

获取日期区块中行列索引指向的子区rect位置与尺寸

---------------------------

0 1 2 3 4 5 6 rowIdx = 0

---------------------------

---------------------------

0 1 2 3 4 5 6 rowIdx = 1

---------------------------

---------------------------

0 1 2 3 4 5 6 rowIdx = 2

---------------------------

---------------------------

0 1 2 3 4 5 6 rowIdx = 3

---------------------------

---------------------------

0 1 2 3 4 5 6 rowIdx = 4

---------------------------

---------------------------

0 1 2 3 4 5 6 rowIdx = 5

---------------------------

一个月总是在28--31天之间,由于星期要缩进,因此6行7列足够解决由于星期缩进引起的显示不全问题

用于绘图以及碰撞检测,共计42个单元格

以二维方式获取日期区块中索引指向的子区的rect位置与尺寸

*/

void calendar_get_day_cell_rect(const SCalendar* calendar,CGRect* rect,int rowIdx,int columIdx)

{

assert(calendar && rect && rowIdx >= 0 && rowIdx < 6 && columIdx >= 0 && columIdx < 7 );

float cellWidth = calendar->size.width / 7.0F;

float cellHeight = calendar->daySectionHeight / 6.0F;

rect->origin.x = cellWidth * columIdx;

rect->origin.y = cellHeight * rowIdx;

rect->size.width = cellWidth;

rect->size.height = cellHeight;

}

/*

blf:

以一维方式方式获取日期区块中索引指向的子区的rect位置与尺寸

*/

void calendar_get_day_cell_rect_by_index(const SCalendar* calendar,CGRect* rect,int idx)

{

assert(calendar && rect && idx >= 0 && idx < 42);

// (/ 和 %)符号的应用,用于计算出行列索引号

int rowIdx = (idx / 7);

int columIdx = (idx % 7);

calendar_get_day_cell_rect(calendar, rect, rowIdx, columIdx);

}

/*

blf:

检测touchPoint是否点击在日期区块的某一个cell中

如果检测到有cell被点中,返回索引

否则返回-1

0 1 2 3 4 5 6 week section

---------------------------

1 rowIdx = 0

---------------------------

---------------------------

2 3 4 5 6 7 8 rowIdx = 1

---------------------------

---------------------------

9 10 11 12 13 14 15 rowIdx = 2

---------------------------

---------------------------

16 17 18 19 20 21 22 rowIdx = 3

---------------------------

---------------------------

23 24 24 25 26 27 28 rowIdx = 4

---------------------------

---------------------------

30 31 rowIdx = 5

---------------------------

注意: 参数localPt是相对于你所继承的View的左上角[0,0]的偏移量,是定义在View空间坐标系的

*/

int calendar_get_hitted_day_cell_index(const SCalendar* calendar, CGPoint localPt)

{

//优化1: 如果一个点不在日期区块中,那么肯定没点中,立即返回

CGRect daySec;

calendar_get_day_section_rect(calendar, &daySec);

if(!CGRectContainsPoint(daySec,localPt))

return -1;

localPt.y -= daySec.origin.y;

//触摸点肯定会会点中日期区块中的某个cell

//优化2: 避免使用循环6*7次遍历整个cell,检测是否一点在该cell中,通过下面算法,可以立刻获得当前点所在的cell行列索引号

float cellWidth = daySec.size.width / 7.0F;

float cellHeight = daySec.size.height / 6.0F;

int columIdx = localPt.x / cellWidth;

int rowIdx = localPt.y / cellHeight;

//检测当前被点中的cell是否允许被选中,具体原理请参考

//函数void calendar_set_year_month(SCalendar* calendar,int year,int month)的注释

int idx = rowIdx * 7 + columIdx;

if(idx < calendar->dayBeginIdx idx > calendar->dayBeginIdx + calendar->dayCount - 1)

return -1;

//到此说明肯定有点中的cell,返回该cell的索引号

return idx;

}

第一部分完毕,下一篇我们关注ios的实现。

打开App,阅读手记

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值