1.设计摘要
想必大家对学校的悬赏互助群并不陌生,学生们在群里提出要求并标明价格,就可以找人帮忙。我们的跑腿平台就是以此为灵感,让学生之间通过一个专门的020平台实现有报酬的互助跑腿,但是相比QQ、微信群,我们让定价更标准、跑腿更安全。
因为学校的区域性市场,校园跑腿经济正在流行,包括代拿快递、代寄快递、代买东西等,支付相应的报酬,互惠互利的事情。校园周边几公里范围内的跑腿代办服务,按照约定的时间完成任务比快递小哥的服务更好更快。
不需要走出校园,在校园内就能完成各类跑腿业务。跑腿经济成为一个契机,成为校园生活服务中的一个创业途径。现在,跑腿不仅是那些需要勤工俭学的同学的专利,还有一些想创业的大学生也看好这块市场。虽然有些大学生每个月的生活费有1000多,但是他们仍然想体验一下生活。
大学的课程本来就少,除了上课,去图书馆自习之外,大部分时间都是在干一些没有意义的事情:男生在寝室打游戏,女生在寝室看视频,不可能一整天抱着书本啃。与其在寝室里面浑浑噩噩,不如走出去参加实践活动,在这些过程中会遇到形形色色的大学生,多交一些良师益友,代拿快递每天花费一小时虽然很辛苦,但是仍然是非常有意义的。
校园跑腿虽然看似很简单,实际上校园最后一公里配送调度是相对来说有一点难度的,需要处理一些临时突发情况,提前储备好跑腿员,使每个跑腿员利益最大化。
2.设计的模式及产品目标
本产品主要采用O2O的模式。
2.1用户方面
在现在的大学校园之中,由于上课、生病等主客观原因,存在有很大一部分学生不能够或不愿意取快递,拿外卖或者买药。这为我们提供了一个庞大的用户群。学生需要有人为他们提供拿外卖,取快递,买药等跑腿服务,当然这是有偿的。此时,使用“我来拿”app便能够为学生及时安全的这类服务,来满足学生的需求。
2.2接单方面:
对于某些学生,在空闲的时候他们会去寻找简直工作来满足自己生活的额外开支,此时我们便为他们提供了一个兼职岗位,工作强度小,工作地点是在自己的校园之内(安全,便利);甚至对于一些社会人员来说,这也提供了工作岗位。既有卖方资源,也有买方资源,一举两得。
3.设计的创新与优势
“我来拿”APP采取线上交流和支付,线下提供服务的模式。对于用户来说“我来拿”除了提供用户一个可以找人帮忙跑腿的平台,同时也可以自己接单跑腿赚钱。学生们日常的事物将会因为“我来拿”APP变的更加方便快捷。
“我来拿”app便能够为学生及时安全的这类服务,来满足学生的需求。不仅是那些需要勤工俭学的同学的专利,也是我们多交一些良师益友的机会,代拿快递每天花费一小时虽然很辛苦,但是仍然是非常有意义的。
4.设计的具体实现
4.1项目的可行性分析
(1)投资必要性:以目前校园悬赏群和相关跑腿行业的普及程度来看,校园跑腿APP会有较大的市场和较好的环境。由于采用“线上交易,线下服务”的020的模式,更贴近学生们平时使用悬赏群的体验,并且由于比悬赏群更标准和更安全,容易受到学生群体的青睐。
(2)技术可行性:使用APICloud进行前端页面的设计,使用eclipse进行后台的开发,使用Mysql存储用户。
(3)组织可行性:将整个项目分成六个模块,分配给每个组员。我们组为6人小组,每个组员都具备良好的理论知识和实践经验,可以较好的完成所分配的任务。
4.2需求分析
(1)用户找人跑腿模块
(2)用户帮人跑腿模块
(3)个人中心模块
(4)注册登录模块
4.3 项目总体设计
(1)系统结构图
“我来拿”APP一共分为四大模块:用户注册、个人中心、找人跑腿、帮人跑腿。
(2)总共能概述
A.用户注册
用户在使用“我来拿”APP时依靠手机号注册,之后完善包括姓名、年龄、性别、所处学校等信息。可以绑定银行卡、支付宝或微信进行订单的支付。我们会保障用户提供的个人信息不被泄露,同时营造一个真实可靠、合法有序的平台环境。
B.个人中心
(1)个人资料:用户可在此处添加、修改自己的个人信息。
(2)钱包:用户可以绑定银行卡或者支付宝等。
1)余额:余额的钱可用于在此APP上的消费,用户通过接单所得收益也将存入余额并在此处显示。
2)提现:余额里的钱可提现至绑定的银行卡或者支付宝等。
3)优惠券:系统会不定时发放一些优惠券,发放的优惠券在此处可查看,消费时可用优惠券,不可抵现。
(3)我的订单:在此处用户可以查看自己以前的消费订单记录和接单记录.
(4)加入我们:用户可以点击“加入我们”申请加入我们的专业跑腿团队,之后会转入一个注册界面,这个界面比用户注册更为详细,且要上传身份证等信息进行实名制。经过审核通过后即可成为一名“天速星”,可以接收“神速跑腿”订单。
(5)客服:显示客服电话,用户如有什么问题可打电话咨询。
(6)设置:点击此处会出现清理缓存、意见反馈、关于我们、退出登录等几个功能。
C.找人跑腿
在找人跑腿界面,有代取快递、代打印、代送东西、代买东西和自定义五个选项。
如果选择前四个选项中的一个,只要在给出的地图上选择起始地点(如快递点、超市、打印店)和目的地址(如宿舍、某教室),就会根据距离自动计算跑腿费用。用户需填写订单的要求,比如打印的格式要求、具体买的东西、快递的编号等等。其中一些要求可以在有人接受了订单后再私聊,比如快递取件需要的手机尾号等较为私密的信息。此外,你可以选择普通跑腿和神速跑腿,如果选择神速跑腿,则会由跑腿团队接单,以更快的接单速度、更快更安全的跑腿完成订单,同时也会支付略高的跑腿费用。即使选择普通跑腿,在情况紧急或有特殊要求的情况下,可以通过在定价基础上加钱的方式以谋取更快的接单或完成特殊的要求。
如果用户想找人做一些无法按距离定价的跑腿任务,比如代排队、代搬东西等,则可以选择自定义选项,在订单要求中详细写出订单的具体事项,并按自己的理解自定义价格。
在提交订单后,就可以等待接单了,在有其他用户接单后,会显示该用户的基本信息和诚信值,用户可以根据给出的信息选择取消接单。当有多个用户接单时,可以根据信息选择一个用户为自己跑腿。只有在用户确定了跑腿人之后,订单才开始生效。
D.为人跑腿
若是普通用户,在为人跑腿界面,可以看到其他用户发出的普通跑腿订单,可以选择订单进行接受。
若是“天速星”用户,在为人跑腿界面,可以看到其他用户发出的普通跑腿订单和神速跑腿订单。
4.4项目的详细设计与实现
(1)找人跑腿模块
在本次关于APP开发的课程设计过程中,我主要设计并开发了项目“我来拿”的主体框架的第一部分,即关于“找人跑腿”部分前端所有页面的规划、设计和具体的开发实现。其中“找人跑腿”部分详细地划分成了5个具体的小模块,分别是“取快递”、“打印”、“取东西”、“送东西”、“自定义”五个方面。关于第一部分“找人跑腿”的具体框架如图4-1。
在设计功能页面的过程中参考了“美团”的界面架构和设计理念,根据对开发的“我来拿”APP的设策划,通过“APICloud”软件进行代码的编写,利用“模拟器MUMU”显示设计结果。具体工具如下图4-2、图4-3。
基于上述准备,具体实现“我来拿”主体框架的“找人跑腿”部分。
首先进行“找人跑腿”部分的主页面设计,基础要求为有关于“取快递”、“打印”、“取东西”、“送东西”、“自定义”五个方面的选项按键。通过编写代码程序、调试运行、修改完善等步骤,确定了关于页面显示布局的参数定义以及最后功能代码的编写。部分代码如下图4-4、图4-5所示。
通过对功能的不断完善和对架构的调整,最后得到如图4-6所示的“找人跑腿”部分的主页面。
根据规划项目初始阶段对“我来拿”APP的功能设计和运营模式的确定,对于“找人跑腿”部分,希望依据“距离”进行跑腿业务的金额计算,同时可根据个人情况进行自主定义,即依据自身情况进行“普通跑腿”、“神速跑腿”的个性化选择并且在“普通跑腿”时也可选择是否加急。通过对功能的明确,设计在页面中具备“起始地、目的地、备注”的用户自主输入框、“普通、加急”的单选按钮、进行金额的计算的输出框、是否进行进一步加急按键,以及最后的“确定、取消”按钮。在如上功能是设计的基础上,进行代码的编写来具体的功能实现。部分代码如下图4-7所示。
通过实现规划部分的功能,最后得到如下图4-8所示的界面。
(2)帮人跑腿模块第一部分
在本次关于APP开发的课程设计过程中,我主要设计并开发了项目“我来拿”的主体框架的第二部分的框架,即关于“帮人跑腿”部分前端筛选页面的规划、设计和具体的开发实现。其中“帮人跑腿”部分详细地划分成了5个具体的小模块,分别是“代取快递”、“代打印”、“代取东西”、“代送东西”、“自定义”五个方面。
在设计功能页面的过程中参考了“美团”的界面架构和设计理念,根据对开发的“我来拿”APP的设策划,通过“APICloud”软件进行代码的编写,利用“模拟器MUMU”显示设计结果。具体工具如下图4-9、图4-10。
基于上述准备,具体实现“我来拿”主体框架的“找人跑腿”部分。
首先进行“找人跑腿”部分的主页面设计,基础要求为有关于“代取快递”、“代打印”、“代取东西”、“代送东西”、“自定义”五个方面的选项按键。通过编写代码程序、调试运行、修改完善等步骤,确定了关于页面显示布局的参数定义以及最后功能代码的编写。部分代码如下图4-11、图4-12所示。
通过对功能的不断完善和对架构的调整,最后得到如图4-13所示的“帮人跑腿”部分的主页面。
根据规划项目初始阶段对“我来拿”APP的功能设计和运营模式的确定,对于“帮人跑腿”部分,因为我负责的是上方的搜索及筛选部分,所以根据不同情况和条件来帮助用户更方便快捷的找到自己顺路的单子。在如上功能是设计的基础上,进行代码的编写来具体的功能实现。部分代码如下图4-6所示。
通过实现规划部分的功能,最后得到如下图4-15所示的界面。
(3)帮人跑腿模块第二部分
主要负责于前端展示设计,使用了一些简单的Bootstrap框架,大部分用HTML5、CSS3以及JavaScript实现了app的部分界面,通过Skeleton(js+css)实现了一些用户交互,通过js模块可对内容进行查询等功能,增加了该软件的功能,通过css对原有的界面进行了加工美化,实现了较好的人机交互页面,从而提高了用户体验和用户满意度。
首先,我使用了APICloud进行具体的代码实现,APICloud登录状况如下:
我完成的全部页面(14个HTML页面)如下图所示:
订单要求及细节:如果有人想接单,查询是否顺路或满足要求时,可查询订单的详细部分。
通过该页面可以进行抢单和查询订单具体需求,以便判断是否要进行抢单,以及抢单之后如何联系单主。 在抢单过程中由于涉及到数据库,若不加以控制,可能会出现数据库混乱现象,即一个单同时被好几个人抢,所以要进行事务处理,将抢单设计成一个完整的事务会避免此情况的发生。 订单的头部样式:
(4)个人中心模块
在本次关于APP开发的课程设计过程中,我主要设计并开发了项目“我来拿”的主体框架的第三部分,即关于“个人中心”部分前端所有页面的规划、设计和具体的开发实现。其中“个人中心”部分详细地划分成了6个具体的小模块,分别是“个人资料”、“我的订单”、“钱包”、“加入我们”、“客服”、“设置”六个方面。具体框架如图4-22。
在设计功能页面的过程中参考了“美团”的界面架构和设计理念,根据对“我来拿”APP的设计和策划,通过“APICloud”软件进行代码的编写,利用“模拟器MUMU”显示设计结果。具体工具如下图4-23、图4-24。
基于上述准备,具体实现“我来拿”主体框架的“个人中心”部分。
首先进行“个人中心”部分的主页面设计,基础要求为有关于“个人资料”、“我的订单”、“钱包”、“加入我们”、“客服”、“设置”六个方面的选项按键。通过编写代码程序、调试运行、修改完善等步骤,确定了页面布局并进行代码的编写。部分代码如下图4-25、图4-26所示。
通过不断的调试,最终得到的个人中心页面如下图4-27:
对于个人资料部分,我们显示现有资料,并提供修改功能,代码和具体页面如下:
对于我的订单部分,显示历史订单并可以点击查看订单详情:
对于加入我们部分,可以填写更为详细的个人资料并提交申请,加入我们的专业跑腿团队:
对于设置部分,我们提供图片设置、消息提醒设置、清除缓存、版本更新、自动下载安装包、关于我们等功能。
(5)注册登录界面以及项目汇报PPT
在本次关于APP开发的课程设计过程中,我主要设计并开发了项目“我来拿”的主体框架的注册登录界面的规划、设计和具体的开发实现。并在项目完成后,为小组做了项目汇报的PPT。
通过编写代码程序、调试运行、修改完善等步骤,完成了注册登录页面,部分代码如下:
在项目结束之后,我负责制作的项目汇报PPT如下图所示:
(6)后端开发
由于时间的紧迫,在此,我们只对登录和注册功能进行了实现。通过MySQL数据库和java,tomcat,jdbc等工具和技术进行实现。
通过按钮的点击事件来调用函数login(登录函数)和register(注册函数)。数据库采用mysql数据库,其优点是小型便利及其强大的功能;在项目中加入了jquery模块使手机app能够访问本地的服务器。使用java web的MVC模式,通过调用servlet来调用后端数据库。
登录功能的实现,按钮点击事件后,通过本地服务器调用servlet模块,在本模块中,根据用户名和密码对数据库内的记录进行查找。若需找到,则允许登录,否则将拒绝登录。
注册功能的实现与登录功能相类似,只不过使用的是数据库的插入操作。当用户输入个人信息之后,首先根据用户名去查找本地数据库中是否存在用户名相同的记录,若存在,则要求用户重新输入;不存在,则将用户信息写入数据库中,注册成功。
在后端代码的实现中,还可以使用连接池,javabean等技术对其进行优化。
4.5项目的测试与运行
(1)找人跑腿模块
由于APP的“找人跑腿”部分只是实现了前端的界面,所以本部分的测试只采用“黑盒测试”进行功能上的测试,检测每个功能是否都能正常使用。
首先,关于“找人跑腿”的主体部分,生成快速测试包后,对功能进行预期核对测试。
如图4-46所示,页面大体分为三个部分,上-中-下。上方页面,将“找人跑腿”部分所需实现的功能模块排为一列,分别有属于自己的图标和名称;中间页面,为太原理工大学标志性建筑图片,经过PS进行动漫风格的处理;下方页面,是“我来拿”APP的三大功能模块选项。经测试,布局及其尺寸参数均与设定相同,故该部分测试结果为“符合预期”。
其次,进行“取快递”页面的黑盒测试。
预期结果为页面中具备“起始地、目的地、备注”的用户自主输入框、“普通、加急”的单选按钮、进行金额的计算的输出框、是否进行进一步加急按键(通过点击加1和减1按钮进行自主选择加急程度),以及最后的“确定、取消”按钮。除了具备以上简述的功能外,要求界面美观,符合市场上大部分APP的审美标准。
如上图4-47所示为“取快递”最开始调试出的测试结果。第一,关于“普通、加急”方面的按钮紧挨在一起,不能在屏幕宽度上进行均匀分布;第二,“金额”字体过大,影响整体的美观度;第三,进行自主选择加急程度的加急按键(加1和减1按钮)未与“金额”在同一行(理想界面要分布与一行)。
通过进一步检查代码,分析出现该现象的原因,发现是表格的参数设置条件写错了地方,造成未能按设置的参数进行显示。
针对所出现的问题进行了代码的修改完善,将对于表格部分的设置进行了如下图4-48所示的更正。
通过对出现的问题进行及时的更改,最终得到了如图4-49所示的最终结果。
其余四个界面的测试参考“取快递”部分。
(2)帮人跑腿模块第一部分
由于APP的“帮人跑腿”框架部分只是实现了前端的界面,所以本部分的测试只检测每个功能是否都能正常使用。
首先,关于“帮人跑腿”的框架部分,生成快速测试包后,对功能进行预期核对测试。
如图4-50所示,框架大体分为三个部分,左-中-右。最左边是搜索框,框中有语音输入功能,在其右边是搜索按钮,最后一个是筛选按钮,点击筛选按钮会进入筛选界面,从而进行更方便的选择性帮人跑腿。经测试,布局及其尺寸参数均与设定相同,故该部分测试结果为“符合预期”。
(3)找人跑腿模块第二部分
我主要负责设计前端部分,前端的代码漏洞往往比纯粹的后台漏洞更难发现,因为前端页面即使有错误语句也不会报错,仍然会正常进行,在调试代码时如果对自己写的代码没有那么了解则极其痛苦。在项目的测试中,我采用了“黑盒”测试和“白盒”测试相结合的方法。首先通过黑盒测试,找到项目中存在的明显问题或者找到不满足设计的地方,通过黑盒测试,实现了以面盖点,总体上不存在问题。然后再进行白盒测试,由于html语言容错性及其强,所以再写html语言时最好就要严谨小心一点,在事后进行白盒测试则工作量相当的大。所以应该采取按模块进行白盒测试,即每一个模块单拿出来进行白盒测试,确保每一个模块本身没问题,再测试模块组合后是否会产生问题,从而解决了前端设计的测试难关。
具体测试情况如下:
首先通过此页面,判断订单是否异常,是否可查看订单具体详情。
其次通过查看订单详情,判断是否可正常接单。
以上部分由于是直接面向用户,故进行黑盒测试,测试功能是否可用即可。
接下来为了使程序有良好的健壮性,所以要进行白盒测试,测试语句是否存在问题,或存在隐藏的漏洞。
在白盒测试过程,由于测试量较大,可进行分模块测试,而且其中有很多模块使类似的,所以可以通过测试一个点,进而测试到一个面。
在测试过程中遇到很多问题,由于是面向前端,所以主要是通过黑盒测试发现了程序中的问题。最终运行结果正常。
(4)个人中心模块
由于APP的“个人中心”部分只是实现了前端的界面,所以本部分的测试只采用“黑盒测试”进行功能上的测试,检测每个功能是否都能正常使用。
首先,关于“个人中心”的主体部分,生成快速测试包后,对功能进行预期核对测试。
如图所示,编写的个人中心页面基本符合预期。
其次,对个人中心的各个子界面进行核对测试。
如图所示,编写的各个页面基本符合预期。
(5)登陆注册模块
由于我负责的注册登录部分只是实现了前端的界面,所以本部分的测试只采用“黑盒测试”进行功能上的测试,检测每个功能是否都能正常使用。
首先是登录页面:
其次是注册页面:
如图所示,登录注册页面基本符合预期。
(6)后端开发
在后端的实现中,我们第一个遇到的问题便是无法访问到本地的服务器,本问题是由两个问题导致的:
·jquery模块。我们在首次的测试中并没有加入jquery模块,导致我们没法访问到后端服务器,于是我们在项目目录下加入了这个模块。如图所示。
·访问servlet的途径不对。在加入了jquery模块之后,我们还是访问不了本地的服务器,我们以为使数据传参的问题,经过实验,参数的传递并没有传递错误;此后,我们直接通过网页的方式访问servlet,这时我们发现自己的访问路径写错了,如图所示。经过修改路径,我们便能够成功地访问数据库了。
5.项目组成员分工
组长:学生1:个人中心模块。
学生2:“找人跑腿”模块。
学生3:“帮人跑腿”模块的第一部分。
学生4:“帮人跑腿”模块的第二部分。
学生5:登陆注册页面和项目汇报PPT。
学生5:后端开发。
6.心得体会
学生1:作为一名计算机专业的学生,平时在使用各种APP时,都会想到是否也可以做一款属于自己的APP,但是因为没有老师进行指导,也没有相关的他人经验可以参考,所以一直没有勇气去真正的实践。得知期末的课设是做一款APP,很想通过此次机会实现以前的很多想法。在进行组内讨论、分工之后,我负责做三大主体部分的第一主体部分——“找人跑腿”前端功能的实现。着手实现之前,为了明确全局的功能,我先绘制了结构框图,随后我的任务部分都是根据框图的架构进行具体实现的。首先,整个课设的过程中,最不容易的时候就是修改代码中相关布局的参数,很多时候都是已经进行了相应的修改,但是却没有达到预期的效果,最重要的是不知道问题出在哪里,修改都无从下手,更担心修改后会影响其他部分的布局结构,基本上就是用半天时间规划功能、编写代码,却要花费四到五倍的时间修改代码。其次,“APICloud”开发工具在生成快速测试包时很慢,为了在模拟器上看到修改的变化,需要等很长时间,由于修改的频繁,浪费了很多时间。最后,就是在将自己实现的部分插入APP整体时,用了一些时间找到相应的入口。虽然算不上历经坎坷,但是在实现APP的功能时,也花费了很多精力,不过最后守得云开见月明,结果让人觉得很值得。
学生2:本次课设要求做一个应用类app,但由于第一周要考研,所以在第二周才得以全身心地参与到课设中。在本次课设中有很多的心得体会,更多的是同学之间的合作,在我参与到课设的时候,整体构架已经成型,在组长的分配下,我负责了第二个模块的框架及筛选部分的内容并且在为期几天的学习过程中学到了很多知识,受益匪浅。在课上,老师举出了一些简单的例子,紧接着当天上午我们开始上机操作,这样可以及时地巩固我们所学的知识点。其次在这次制作软件中,我觉得小组的分工与协作是非常重要的,如果不分工,这样就会导致作品出错,而且会浪费时间,比如说:在没有明确的分工下,我找资料,我的组员也去找资料,这样就会导致工作重复,浪费一定的时间。所以说合作的关键在于同心、分工明确。幸好我们小组分工明确,这样才按时完成任务。 总之,在这次学习中,我获得了很多东西,提高了自己的编程技巧和编程方法,并且认识了手机app应用程序的开发,以及加深了对html和Javascript的认识。
学生3:在课程设计开始阶段,组建项目的时候遇到了一些问题,比如可行性分析的时候如何利用此app进行获益,如何保障安全,如何实现比较友好的人机交互界面等等都存在一些困惑。不过,经过大量的查阅资料以及请教老师的方式,我们终于攻克了一个又一个的难关,我自身觉得在开发过程中有不懂的先去自己查阅资料,如果没有什么好的结果或者很费力,应该主动去询问老师如何解决,查阅资料的过程也是自身完善和学习的过程。我们应该加强对自己代码的训练量,通过一次一次的课程设计加强自身的合作能力和团队意识。我们的设计思想也是来源于现实的校园生活,而且设计理念也得到了老师的肯定,所以我们应该善于从生活中发现机遇,但发现机遇还远远不够,重要的是去用自己的汗水进行实现,在这过程中难免会遇到一些苦难,我们应该努力认真思考,攻克难题。最后,我衷心的感谢老师,因为没有他们的帮助,我或许完成不了我自己在该课程设计中负责的部分。同时也感谢我的组员,因为我们组员之间每个人都相处的非常融洽,有较好的合作意识,顺利准时的完成了课程设计。
学生4:此次课程设计是我第一次进行APP的开发,具有很高的实践意义。在这次为期两周的课程设计中,我和我的组员们遇到了很多困难,有些错误一上午都难以解决,但是我们没有放弃,反而在课程的过程中逐渐成长,对APICloud的运用逐渐熟练,在后面的课设中,出现的错误也越来越少。然而在最后一天验收前的晚上,我将组员们的模块进行整合的时候,还是出现了莫名的错误,一直解决到接近晚上11点才匆匆回到宿舍。不过好在结果是好的,大家的功能都完成的不错,我们组的最终结果也较为完美的在周四进行了最终呈现。通过这次为期两周的课程设计,大大的提升了我的实践能力,为今后的工作学习打下了坚实的实践基础。
学生5:通过此次课程设计,使我更加扎实的掌握了有关APP开发的知识,在设计的过程中虽然遇到了一些问题,但经过一次又一次的思考,一遍又一遍的检查终于找出了原因所在,也暴露出了前期我在这方面的知识欠缺和经验不足,实践出真知,通过亲自动手,使我们掌握的知识不再是纸上谈兵。这次课程设计终于顺利完成了,在今后社会的发展和学习实践中,一定要不懈努力,不能遇到问题就想要退缩,一定要不厌其烦的发现问题所在,然后一一进行解决。只有这样才能在今后的日子里披荆斩棘,收获成功。
学生6:手机app的开发在当前这个时期十分重要。手机已经成为人们生活中及其重要的一部分,而与手机密切相关的便是手机app,若是没有手机app的存在,那么手机也就没有存在的意义了。通过这次的课程设计,我对于手机app的开发有了初步的认识与理解。app开发包括两个方面,前端设计与后端开发。前端设计通过使用apicloud这个还用的工具来实现图形化界面的设计,使app界面符合用户的需求,达到美观、使用方便等目的。后端开发则是使用数据库等工具使app能够访问到远端服务器上面的数据库,实现具体的功能。在这次实现中我对于前端html页面的设计和MVC模式有了更加深入的理解与掌握。
7.核心代码
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/>
<title>Hello APP</title>
<link rel="stylesheet" type="text/css" href="./css/api.css" />
<link rel="stylesheet" type="text/css" href="./css/common.css" />
<style>
/* 头部样式 */
#firstHeader {background-color: #FF8400;}
.topbar {/*background: #FF8400;*/ height:50px; border-bottom: 1px solid #DDDFE3;}
.topbar_title {display: inline-block;font-size: 20px; line-height: 50px;padding-left: 12px;}
.hr01, .hr02 {height: 28px;}
.headerico {padding: 11px 15px 11px 15px;}
.headericohover {background: #DADDE0;}
.fr{float: right;}
.fl{float: left;}
/*第一头部*/
#logo {padding: 11px 0 0 10px;height: 28px;}
#citylist {height: 50px; line-height: 50px;padding-left: 15px; font-size: 18px; color: #fff;}
.citylistarrow {vertical-align: top; width: 20px; padding-top: 15px;}
.search {height: 34px;line-height: 34px; padding-left: 10px; border-radius: 30px; margin-top: 8px; position: absolute; left: 20px; right: 60px;font-size: 14px;}
.search img {vertical-align: top; width: 20px; padding-top: 7px;padding-right: 10px;}
.firstSearch {left: 90px;right: 60px;background-color: #FA6604;color: #FDC29B;}
/* 第二头部 */
#topbar_refresh {width: 40px;padding:5px 10px;}
.whitebar {background-color: #fcfcfc;}
#whitecity {height: 50px; line-height: 50px;padding-left: 15px; font-size: 18px;color: #FF8400;}
.secCitylistarrow {vertical-align: top; width: 15px; padding-top: 18px;padding-right: 5px;}
.secSearch {left: 15px;right: 150px;background-color: #E8E8E8;color: #999;}
.filter {float: right;right:20px;position:absolute;}
.filter img {width: 25px;padding-top: 10px;padding-right: 10px;}
/* 第三头部 */
/*.swipepic {padding: 5px 15px 2px 15px;height: 23px;}*/
/*.swipe div {font-size: 12px; text-align: center;color: #999;}*/
/*.thrSearch {left: 15px;right: 60px;background-color: #E8E8E8;color: #999;}*/
/* 头部切换样式 */
.titlebar {display: none;}
.activebar {display: block;}
/* 底部切换按钮样式 */
ul {display: -webkit-box; display: -webkit-flex; display: flex; }
#footer {height: 61px; line-height: 60px; background-color: #FAFAFA;border-top: 1px solid #FAFAFA; }
#footer li{-webkit-box-flex: 1; -webkit-flex: 1; flex:1; height: 60px;}
/* 选项卡样式 */
.scrollbar {display: -webkit-box;display: -webkit-flex; text-align: center; height: 40px; line-height: 40px;background: #EBECF0;font-size: 12px;position: relative;}
.col1 {-webkit-box-flex:1;-webkit-flex: 1;flex:1;color: #909090;}
.indexbar {position: absolute;/*background: #0fc;*/width: 50%;height: 5px;left: 0px;bottom: 0px;-webkit-transition: 300ms;}
.redbox {background: #DB4646;width: 40px;height: 5px;position: relative;left: auto;right: auto; margin-left: auto; margin-right: auto;}
/********************/
/* 底部按钮原始样式 */
/********************/
.bbtn01 {background: url(./image/main_index_home_normal.png) no-repeat center 4px; }
.bbtn02 {background: url(./image/main_index_tuan_normal.png) no-repeat center 4px; }
.bbtn03 {background: url(./image/main_index_search_normal.png) no-repeat center 4px; }
.bbtn04 {background: url(./image/main_index_my_normal.png) no-repeat center 4px; }
.bottom_btn {width: 99%; height: 43px;padding-top: 18px;background-position-y: 4px; background-size: 30px; font-size: 12px; color: #A5A5A5;}
/* 底部按钮激活样式 */
.activebtn0 {background: url(./image/main_index_home_pressed.png) no-repeat center 4px; }
.activebtn1 {background: url(./image/main_index_tuan_pressed.png) no-repeat center 4px; }
.activebtn2 {background: url(./image/main_index_search_pressed.png) no-repeat center 4px; }
.activebtn3 {background: url(./image/main_index_my_pressed.png) no-repeat center 4px; }
.activebtn {color:#FF7419; background-size: 30px; }
.bottomhover {background-color: #46494B;}
/* 本地刷新图标 */
#localrefresh {display:none;float: right; width: 40px; padding: 5px 10px;}
.swipe {line-height: 50px;margin-right: 90px;color: #FF8400;}
</style>
</head>
<body>
<div id="wrap">
<!-- 第一头部 -->
<div id="firstHeader" class="titlebar activebar">
<div class="topbar">
<div class="citylist fl" id="citylist" tapmode="" onclick="openCitylist()">北京<img src="./image/title_home_arrow_down_normal.png" alt="" class="citylistarrow"></div>
<div class="search firstSearch" tapmode="" onclick="openSearch()">
<img src="./image/ic_home_search.png" alt="">输入商户名、地点
</div>
<img src="./image/send_msg.png" alt="" class="fr headerico hr01" tapmode="" onclick="openNewWindow('message')">
<!-- <img src="./image/topbar_search.png" alt="" class="fr headerico hr02" tapmode="headericohover" onclick="openNewWindow('search')"> -->
</div>
</div>
<!-- 第二头部 -->
<div id="secHeader" class="titlebar">
<div class="topbar whitebar">
<!--<div class="citylist fl" id="whitecity" tapmode="" onclick="openCitylist()">北京<img src="./image/title_arrow_down_normal.png" alt="" class="secCitylistarrow"></div>-->
<div class="search secSearch" tapmode="">
<img src="./image/navibar_search_icon_search.png" alt="">
<input type="text" placeholder="请输入搜索内容" border="0" id="search1">
<img src="./image/icon_mic_normal.png" alt="" tapmode="" >
</div>
<div class="swipe fr">搜索</div>
<div class="filter"><img src="./image/list_icon_filter.png" alt="" onclick="openNewWindow('filter1')"></div>
<!--<div class="citylist fl" id="whitecity" tapmode="" onclick="openCitylist()">北京<img src="./image/title_arrow_down_normal.png" alt="" class="secCitylistarrow"></div>-->
<!-- <img src="./image/local_icon_refresh.png" alt="" class="fr headerico" id="topbar_refresh" tapmode="headericohover" onclick="emptyopt()">
<img src="./image/topbar_search.png" alt="" class="fr headerico hr02" tapmode="headericohover" onclick="openNewWindow('search')"> -->
</div>
</div>
<!-- 第三头部
<div id="thridHeader" class="titlebar">
<div class="topbar whitebar">
<div class="search thrSearch" tapmode="" onclick="openSearch()">
<img src="./image/navibar_search_icon_search.png" alt="">输入商户名、地点
</div>
<div class="swipe fr" tapmode="headericohover" onclick="openScan()">
<img src="./image/navibar_icon_qr.png" alt="" class="swipepic">
<div>扫一扫</div>
</div>
</div>
</div>-->
<!-- 第四头部 -->
<div id="thirdHeader" class="titlebar">
</div>
<div id="main">
</div>
<div id="footer">
<ul>
<li tapmode="activebtn0 activebtn" onclick="switchframe('first_frame', 0)">
<a class="bottom_btn bbtn01 weixin activebtn activebtn0">找人跑腿</a>
</li>
<li tapmode="activebtn1 activebtn" onclick="switchframe('second_frame', 1)">
<a class="bottom_btn bbtn02 communicate">帮人跑腿</a>
</li>
<li tapmode="activebtn2 activebtn" onclick="switchframe('third_frame', 2)">
<a class="bottom_btn bbtn03 discover">个人中心</a>
</li>
</ul>
</div>
</div>
</body>
<script type="text/javascript" src="./script/api.js"></script>
<script type="text/javascript">
var firstHeader = $api.byId('firstHeader');
var secHeader = $api.byId('secHeader');
var thirdHeader = $api.byId('thridHeader');
var firstHeaderOffset;
var main = $api.byId('main');
var mainPos = $api.offset(main);
var footer = $api.byId('footer');
var footerPos = $api.offset(footer);
var gFrameIndex;
function emptyopt () {}
function openNewWindow(type)
{
api.openWin({
name: type,
url: './html/'+type+'.html',
pageParam: {},
bounces: false,
opaque: false
});
}
function openScan()
{
// api.openWin({
// name: 'scan',
// url: './html/scan.html',
// bounces: false
// });
var obj = api.require('scanner');
obj.open(function(ret,err) {
api.alert({
title: '扫描结果',
msg: ret.msg
});
});
}
function openSearch()
{
api.openWin({
name: 'search',
url: './html/search.html',
bounces: false,
delay:200
});
}
function openCitylist() {
api.openWin({
name: 'citylist',
url: './html/citylist_header.html',
bounces: false,
delay:200
});
}
// 随意切换按钮
function randomSwitchBtn(name, index)
{
var lis = $api.domAll('.bottom_btn');
var i = 0, len = lis.length;
var curLi = lis[index];
for(i; i<len; i++){
var thisLi = lis[i];
if(thisLi === curLi){
$api.addCls(thisLi,'activebtn');
$api.addCls(thisLi,'activebtn'+index);
continue;
}else{
if($api.hasCls(thisLi,'activebtn')){
$api.removeCls(thisLi,'activebtn');
$api.removeCls(thisLi,'activebtn'+i);
}
}
}
// 切换头部
var lis = $api.domAll('.titlebar');
var i = 0, len = lis.length;
var curLi = lis[index];
for(i; i<len; i++){
var thisLi = lis[i];
if(thisLi === curLi){
$api.addCls(thisLi,'activebar');
$api.addCls(thisLi,'activebar'+index);
continue;
}else{
if($api.hasCls(thisLi,'activebar')){
$api.removeCls(thisLi,'activebar');
$api.removeCls(thisLi,'activebar'+i);
}
}
}
}
// 隐藏所有的一级frame
function hideAllFrame()
{
api.setFrameAttr({
name: 'first_frame',
hidden:true
});
api.setFrameAttr({
name: 'second_frame',
hidden:true
});
api.setFrameAttr({
name: 'third_frame',
hidden:true
});
}
// 自己修复ios显示frame的时候bug
// ios自己主动隐藏后,再open就不显示了
function showgroup(type)
{
api.setFrameGroupAttr({
name: type + 'group',
hidden:false
});
}
// 展示指定的frame
function showframe(type)
{
api.setFrameAttr({
name: type,
hidden:false
});
}
// 打开第一个、第三个frame
function openframeinstance( frame, marginTop, isBounce)
{
api.openFrame ({
name: frame,
url: './html/' + frame +'/' + frame + '_body.html',
rect:{
x:0,
y:marginTop,
w:'auto',
h:api.frameHeight - marginTop - footerPos.h
},
pageParam: {name: 'test'},
// bounces: isBounce,
bounces: false,
vScrollBarEnabled:false,
hScrollBarEnabled:false,
delay:200
});
}
// 移动滑动块
function sliderbarCallback(id, num) {
// 得到背景元素的宽度
// var width=parseInt(window.getComputedStyle($api.byId('matchwidth'),null).width);
var width = parseInt(api.frameWidth / 2);
// api.alert({msg:width});
if(num!=0){
num=width;
}
// 移动背景元素的宽度 在index.html不能获得 forth_frame.html上面的dom,虽然是在同一个手机屏幕上
$api.css($api.byId(id),"-webkit-transform:translate(" + num + "px,0)");
}
// ===================================
// 响应底部按钮的切换frame
// ===================================
function switchframe(type, _index)
{
if ( _index === gFrameIndex ) {
return 0;
} else {
gFrameIndex = _index;
}
switch(type)
{
case 'first_frame':
randomSwitchBtn('first_frame', 0);
hideAllFrame();
openframeinstance('first_frame', firstHeaderOffset.h, true);
// showframe('first_frame');
break;
case 'second_frame':
randomSwitchBtn('second_frame', 1);
hideAllFrame();
openframeinstance('second_frame', firstHeaderOffset.h, true);
// showgroup('hot');
break;
case 'third_frame':
randomSwitchBtn('third_frame', 2);
hideAllFrame();
openframeinstance('third_frame', 0, false);
// showframe('third_frame');
break;
default:
break;
}
}
// 完成首页初始化
apiready = function(){
// 设置ios7的标题栏字体变亮,全局用一个就行了
api.setStatusBarStyle({
style: 'dark'
});
firstHeader = $api.byId('firstHeader');
secHeader = $api.byId('secHeader');
thirdHeader = $api.byId('thridHeader');
$api.fixIos7Bar(firstHeader);
$api.fixIos7Bar(secHeader);
$api.fixIos7Bar(thirdHeader);
firstHeaderOffset = $api.offset(firstHeader);
var main = $api.byId('main');
var mainPos = $api.offset(main);
var footer = $api.byId('footer');
var footerPos = $api.offset(footer);
gFrameIndex = 0;
// 第一次进入打开 first_frame body
api.openFrame ({
name: 'first_frame',
url: './html/first_frame/first_frame_body.html',
rect:{
x:0,
y:firstHeaderOffset.h,
w:'auto',
h:api.frameHeight-firstHeaderOffset.h -footerPos.h
},
bounces: false,
opaque: false
// vScrollBarEnabled:false,
// hScrollBarEnabled:false
});
};
</script>
</html>
8.参考文献
参考文献的格式如下:
序号·作者名·书刊名·出版杜·出版时间(刊号)·(小四号宋体)
如:
[1] 杨选辉 .网页设计与制作教程.北京:清华大学出版社.2006
[2] 詹国华,潘红等.多媒体网页设计教程,.北京:高等教育出版社.2009
[3] 贾珺.动态网站设计与开发项目教程, 中国电力出版社.2009
喜欢的点赞收藏加关注私信作者沟通交流