为了账号安全,请及时绑定邮箱和手机立即绑定

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

标签:
Android iOS C++

章节:

1、需求描述以及c/c++实现日期和月历的基本操作

2、ios实现自绘日期选择控件

3、android实现自绘日期选择控件

目的:

通过一个相对复杂的自定义自绘控件来分享:

1、ios以及android自定义自绘控件的开发流程

2、objc与c/c++混合编程

3、android ndk的环境配置,android studio ndk的编译模式,swig在android ndk开发中的作用

一、需求描述以及c/c++实现日期和月历的基本操作

1、需求描述:
图片描述
1) 该日期选择控件主要用于日期过滤查询,一般用于近n年的数据查询。

2) 假设你点击某个按钮弹出该日期选择控件时,自动定位到当前月,例如本月是4月,则4月份显示在屏幕最下方。

3) 当你手指向上滑动时,向前n个月滚动(月份例如:4-3-2-1),手指向下滑动时,向后n个月滚动(月份例如:1-2-3-4)。

4) 日期区分为可选择区或不可选择区(图1),当你第一次点击可选的日期,该日期会被选中(蓝色)。

5) 当你第二次点击可选的日期,则会形成一个选区(图2),该选区会跳过所有不可选的日期。

2、为什么使用c/c++:

1) 历史原因:该控件是两年前为某个项目实现的,当时没有移动开发经验,因此最初技术预研时选择了跨平台的cocos2d-x来开发,并为其实现了该控件.但是cocos2d-x存在一些bug,并且其基于游戏开发模式,不停的循环绘制,cpu占用高,耗电量大。如果要用cocos2d-x开发一般的app的话,需要为其加入脏区局部刷新的功能,这样改动量太大。在研究cocos2d-x时,其所见即所得的cocostudio需要使用swig将c/c++代码wrap成c#供其进行平台调用。当时觉得swig真是强大无比,可以自动wrap为c#,java,python,lua,js....等进行相互调用。

2) ios端objc可以非常容易的与c/c++进行相互调用,而android ndk+swig也可以大大减轻c/c++代码在android端的实现和调用难度(具体我们在第三部分中可以体会到)。这样我们就能够重用为cocos2d-x所写的c/c++代码。

3) 基于java的android程序,非常容易进行反编译,因此使用c/c++编译成.so后,都是二进制代码。因此如果对运行速度或代码安全性有比较高的要求的话,可以使用c/c++进行实现,由android java jni进行调用。

4) 还有一个重要原因就是想深入了解一下android ndk以及swig的开发方式。

3、为什么选择自定义自绘控件方式:

不管是android还是ios,自定义控件的实现基本上有三种方式:

1) 利用androidStudio或xcode interfaceBuilder中的容器控件以及其他控件组合拼装而成,自定义控件不需要继承自View或子类。你可以进行一些事件的编写就可以完成很多需求。

2) 继承自View或子类,再用现有的控件组合拼装而成。

3) 继承自View或子类,所有该自定义View的显示效果由我们来绘制出。 

这里我们采取第三种方式。相对来说,这种方式内存消耗要小很多,并且速度上也有一定优势吧。要知道每个月都是需要42个cell表示日期,并且加上年月和星期这些区块,都用View组合而成,内存也不算小。不管是ios还是android,每个View的成员变量都不少。而使用自绘控件,只要一个View就解决了。至少内存使用上可以减少40多个View的使用,对吧?

4、c/c++实现细节:
1) android中的一些适配结构和函数:
因为使用了ios内置的例如CGRect,CGPoint,CGSize等c语言结构,而android ndk中没有这些结构,因此对于android来说,需要实现这些结构以及在整个程序中用到的一些函数。c/c++中要做到这些,可以使用宏来判断和切换当前的环境,具体见代码:

/*blf: 使用ios中的一些基础数据结构,android中需要移植过来 。  
       ios的话,请将下面 #define ANDROID_NDK_IMP这句代码注释掉!
*/
#define ANDROID_NDK_IMP
#ifdef ANDROID_NDK_IMP 
    typedef struct _CGPoint {    float x;    float y;}CGPoint;
    typedef struct _CGSize  {    float width;    float height;}CGSize;
    typedef struct _CGRect  {    CGPoint origin;    CGSize size;}CGRect;
#endif
/*blf: 使用ios中的一些基础数据结构,android中需要移植过来  
       下面是实现代码
*/
#ifdef ANDROID_NDK_IMP  
    static float GetRectMaxX(CGRect rc) { return rc.origin.x + rc.size.width;  }  
    static float GetRectMaxY(CGRect rc) { return rc.origin.y + rc.size.height; }  
    static bool CGRectContainsPoint(CGRect rc, CGPoint pt){return(pt.x >= rc.origin.x) && (pt.x <= GetRectMaxX(rc)) && (pt.y >= rc.origin.y) && (pt.y <= GetRectMaxY(rc));}
#endif
点击查看更多内容
4人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消