手机版

JavaScript用DeviceOne开发实战(3)模仿微信应用

时间:2021-09-21 来源:互联网 编辑:宝哥软件园 浏览:

这是一系列文件。长期目标是利用DeviceOne开发一些目前广泛使用的高质量手机应用。我们将最大化这些应用的每一个功能和细节,不仅仅是在简单的UI模仿和Demo阶段,而是作为一个基本可以使用的实用app。

在实现过程中会遇到很多困难,会发现目前由于缺少组件支持,有些功能无法实现,在各种移动开发中也会遇到一些常见的技术问题。一步一步的操作和解决问题,可以帮助开发者直观地了解如何通过DeviceOne开发一个实际的App,也可以了解移动开发本身的很多技术细节,可以帮助App开发者少走很多弯路。

本文主要介绍微信的模仿。

第一部分是框架的构建。

而且一般App的开发都需要产品人员的UE设计和美工人员的UI设计,只有这两个步骤完成之后,功能实现才开始。现在我们在模仿现有的微信,所以这些步骤可以省略。看下图,是美工提供的主界面UI设计图,里面的元素标注了尺寸。

1.新项目:我们选择了Simple模板,之所以选择空模板,是因为我们可以更详细地解释开发过程。实际上,多视图带视图淋浴模板更适合这个项目。

2.简要分析主界面。整个主界面的尺寸是iphone6尺寸750*1334。它分为上下两部分。底部是底部栏导航栏,上面有四个独立的界面。这四个界面中始终只显示一个,其他三个界面在内存中,通过底部导航进行切换。这个适合用do _ ViewShower作为框架的主体如下:

根据这个设计,我们在新项目上删除了自动生成的按钮,添加了一个do_ALayout组件和一个do _ ViewShower组件,并设置了它们的高度和宽度以及x,y坐标:

3.接下来,我们将添加4个视图淋浴页面。在这里,我还要强调,实际App会有很多人参与。我们的代码结构要清晰易读,尽量用英文命名。用中文拼写真的是不可能的,包括建立多级子目录。不要把它们混在一起。在这里,我们添加了四个子目录:聊天、联系人、发现、我。右键单击每个子目录,选择新建-其他-设备一ui文件,创建四个index.ui,会自动生成对应的index.ui.js。

注意将这四个ui文件对应的根节点ALayout的高度设置为1220,因为这四个ui文件都是主界面viewserver的子视图,不应该超过viewserver的大小。

此外,每个ui都增加了一个标签,标注中文名称,但调试后真实效果会更清晰。

4.只需在4个按钮中添加4个按钮。底部栏,然后添加相应的js代码,实现ViewShower的页面切换功能。这里有一个技巧。如果选择两个或多个元件,可以使用各种对齐功能,如下图所示:

5.在index.ui.js中添加由ViewShower初始化的代码和按钮的click事件

var view bear=ui(' view bear ');var Page=sm(' do _ Page ');//添加4个子页面到view buffer。添加视图([{id:' chats ',//page的路径: ' source 3360//view/chats/index . ui '//page的路径),{id3360' contacts ',路径: ' source ://view/contacts/index . ui ' },{ id : 'discover ',路径: ' source ://view/discover/index . ui ' },{ id : 'me ',路径3://初始化第一页,viewserver . showview(' chats ');var Button 1=ui(' do _ Button _ 1 ');button1.on('touch ',function(){ viewserver . show view(' chats ');});var Button 2=ui(' do _ Button _ 2 ');button2.on('touch ',function(){ viewserver . show view(' contacts ');});var Button 3=ui(' do _ Button _ 3 ');button3.on('touch ',function(){ view buffer . show view(' discover ');});var Button 4=ui(' do _ Button _ 4 ');button4.on('touch ',function(){ viewserver . show view(' me ');});6.先来看看真机的运行效果,启动设计师的调试服务,在手机上启动调试程序。最后,我们可以看到下面的效果图。iOS和安卓的界面完全一样。点击底部四个按钮,切换效果不错:

7.这一节到此结束。框架工作完成了吗?只能说框架的第一步完成了。如果我们有很多同事一起开发这个App,我们可以分开并行开始工作,然后分成五个部分:

* bottom bar */chats/index . ui */contacts/index . ui */discover/index . ui */me/index . ui多人并行工作的前提是代码版本管理,比如我们这里用到的SVN和GIT。地址是https://github.com/do-project/Fake-Weixin.在每个部分之后,我们将提交GIT服务。可以下载这个节点的代码引用。我们还会将本节的项目代码附在附件中。

在下一节中,我们完成了第一个子任务,BottomBar的实现。

-

本节主要完成底部导航栏的实现。

0.先分析一下界面效果图和设计图。

整个底部导航分为四个重复的部分,每个部分都由图片ImageView、底部标题Label和右上角标记。这个标签可以通过圆形标签来实现,默认情况下应该是隐藏的。

1.第一步是找到相应的图片资源,通常是艺术家提供的。现在我们模仿微信。最好的方法是从微信原生安装包中获取它们。我们可以打开微信ios和安卓安装包,而不是直接依赖截图。ios安装包是ipa,安卓安装包apk都是压缩文件,所以我们可以通过解包得到一些图片资源。目前我只需要最下面的8个图标,包括非点和点中突出显示的图标,把这些图标放在外面的图像目录中。

2.首先删除之前添加的4个临时按钮,然后根据美工提供的尺寸数据布局新的组件,包括4个do_ImageView组件、4个Label组件和右上角的4个标签。简单计算表明,ImageView的大小为60*60。这里有一个技巧。设置一组图像视图和标签后,选择两个组件,然后右键单击“复制”,然后“粘贴”三次。也可以为各种路线选择多个构件。

再微调一下,把图文设置好。图片设置是设置ImageView的源属性,标签需要设置文本中心,设置textAlign属性为center,设置字体,设置背景色、前景色等。并将右上角三个标签的可见性设置为false。在中间添加一个ALayout,将背景设置为灰色,用作视图淋浴和底部栏之间的分界线。这里需要注意的是,右上角的右圆形Label的实现是设置边框属性,边框设置为FF0000FF,1,15,其中1,15表示边界线颜色为红色,宽度为1,半径为15(标签的宽度和高度均为30),从而实现了右圆形。

在真机上测试效果。iPhone和安卓手机的效果图如下:

忽略

3.这个时候,就会出现两个问题。如果在ImageView中添加点击事件,用户必须点击这张图片才能触发点击,所以体验不好。第二个问题是在安卓上画面略有失真。比如在iPhone4上,圆圈可能会变成椭圆形。这个问题是因为不同手机的长宽比不同。

解决方案是:

*将四个大小相同的子ALayout添加到底部栏所在的ALayout中,然后将imageview和label放在相应的子ALayout上,再将click事件添加到子ALayout中,这样用户的手指只要触碰到相同的位置就可以触发事件。*将上述四个子布局的isStretch属性更改为false。这个原理可以参考alayout文档的演示。

4.修改index.ui.js,添加代码主要是修改底部栏切换按钮时所有图标的颜色和单词的前景色。

var Button=ui(' do _ Button _ ');var ImageView=ui(' do _ ImageView _ ');var Label=ui(' do _ Label _ ');button.on('touch ',function(){ show view(' chats ');});var Button=ui(' do _ Button _ ');var ImageView=ui(' do _ ImageView _ ');var Label=ui(' do _ Label _ ');button.on('touch ',function(){ show view(' contacts ');});var Button=ui(' do _ Button _ ');var ImageView=ui(' do _ ImageView _ ');var Label=ui(' do _ Label _ ');button.on('touch ',function(){ show view(' discover ');});var Button=ui(' do _ Button _ ');var ImageView=ui(' do _ ImageView _ ');var Label=ui(' do _ Label _ ');button.on('touch ',function(){ show view(' me ');});函数show view(name){ viewserver . show view(name);if(name==' chats '){ imageview . source=' source ://image/tab bar _ mainframehl . png ';label . font color=' BBFF ';} else { imageview . source=' source ://image/tab bar _ mainframe . png ';label.fontColor=' FFFFF} if(name==' contacts '){ imageview . source=' source ://image/tab bar _ contact SHL . png ';label . font color=' BBFF ';} else { imageview . source=' source ://image/tab bar _ contacts . png ';label.fontColor=' FFFFF} if(name==' discover '){ imageview . source=' source ://image/tab bar _ discoverhl . png ';label . font color=' BBFF ';} else { imageview . source=' source ://image/tab bar _ discover . png ';label.fontColor=' FFFFF} if(name==' me '){ imageview . source=' source ://image/tab bar _ MeHL . png ';label . font color=' BBFF ';} else { imageview . source=' source ://image/tab bar _ me . png ';label.fontColor=' FFFFF}}到目前为止,底部导航栏已经基本实现,这部分比较简单,主要涉及一些细致的ui拖拽调整。我们看看安卓有了调试版,iOS很有效。

我们开始意识到ViewShower第一页的主要内容。

-

结合版块底部的导航,本版块主要是完成微信四大主页面的首页“微信”。这一节有很多内容,我们将在几篇文章中完成。

照例先分析UI,UI由系统状态栏、工具栏、微信聊天记录列表三部分组成。

1.系统状态栏高度为40,背景为黑色。我们注意到微信首页的四个子页面都有这个系统状态栏,需要做一个整体的框架调整。四个子页面都不需要添加状态栏,只需要在viewserver上添加一个,对应的viewserver和子页面的高度就会变成1180。

应该在相应的设计器中的index.ui、chats/index.ui、contacts/index.ui、discover/index.ui和me/index.ui中更改height和y的属性值。效果如下:

2.让我们回到chats/index.ui,首先在里面添加工具导航栏(高度80)以及标题和工具按钮。此资源文件需要添加一个加号。因为此文件是聊天页面专有的,所以它存在于图像/聊天/酒吧_ add.png下。当我们查看真实的机器效果时,我们注意到顶部有一个额外的黑色区域,这是设计器中添加的状态栏。因为这个页面是从系统状态栏中画出来的,所以设计器中的这个部分是多余的。

解决方法是修改app.js,给openPage添加一个statusBarState参数(API文档),并将其设置为透明,这意味着页面是从屏幕顶部绘制的。

var D1=require(' device one ');var App=D1 . sm(' do _ App ');app.on('loaded ',function(){ this . OpenPage({ source : ' source ://view/index . ui ',status base state : ' transparent ' });});让我们来看看真实的机器渲染图:

3.主要部分是一个do_ListView。接下来,设置ListView的单元格和数据。列表视图的单元格引用列表框的每一行。比如ListView有100行数据,但实际上可见的屏幕永远只能看到8、9行左右。因此,当我们手势上下滑动时,我们没有创建100行,而是重用了这8行或9行,只替换了里面的数据。我们称之为行模板,它也是DeviceOne中的一个ui文件。例如,这里我们在chats子目录中创建新的chat_cell.ui,基本ui界面如下:

根据艺术家的设计大小,我们拖拽UI。

这里也要考虑纯圆变形的问题,设置文字大小、前景色等属性。可以看到其中有很多do _ label和do _ imageview组件。因为模板ui依赖后期数据绑定,所以在设计阶段是空白的。

接下来需要设计chat_cell.ui对应的数据,通常为了用户体验,需要尽量减少网络交互。打开页面时,我们通常先读取本地数据文件,显示界面,再考虑是否连接网络获取最新数据。因此,App开发需要仔细考虑数据本地读写和数据时效性之间的平衡。DeviceOne传输的数据基本上是标准的JSON格式。下图展示了chat_cell.ui中组件属性与JSON数据结构的对应关系。

映射关系的代码如下在chat_cell.ui.js中我们可以看到,映射关系的左侧是组件id。组件属性名,右侧是数据JSON的键名:

//与chat_cell.uivar root=ui('$ ')相关;//$是此ui文件的根节点组件的通配符。如果指定了组件的id,还可以使用该id获取对象root . setmapping({ ' photo _ imageview . source ' : ' photo ',' name _ label.text' :' name ',' last message _ label . text ' : ' last message . message ',' last time _ label . text ' : ' last message . time ',' unread _ label . visible ' : ' unread-count ',' name _ label . font。相应的数据应该是第一次从网络获取,然后在本地缓存。我们正在模拟,所以我们首先手动生成一个文件到data/chats/chat.json。

4.我们回到chats/index.ui我们需要在这里的ui文件中为listview设置模板并绑定数据。将index.ui中listview的templates属性设置为source ://view/chats/chat _ cell.ui注意:chat _ cell . ui存储在source/default/view/chats/chat _ cell . ui中,但source 3360//的根节点是指index.ui.js中的source/default/directory

//与index . uivar Storage=sm(' do _ Storage ')相关;var ListData=mm(' do _ ListData ');var list view=ui(' list view ');var JSON _ path=' data ://chats/chat . JSON ';//本地缓存数据if(storage . file exists(JSON _ path)){ storage . read file(JSON _ path,function (data,e)){//device one . print(JSON . string(data));listdata.addData(数据);listview . BindItems(list data);listview . refresh items();})} var Page=sm(' do _ Page ');Page.on('loaded ',function(){ //该事件在页面加载并显示后触发。//我们可以在本次活动中获取最新的网络数据来更新listview和data/chats/chat . JSON });让我们看看在真机上的效果。

操作中有几个细节:

*上下滑动时,画面不断刷新。原因是我们ImageView的来源是网络图片,每次显示都是从网络上获取的。因此,需要将chat_cell.ui中ImageView的cacheType属性更改为“always”,这意味着一旦从网络中读取,就会在本地缓存,下次不会再从网络中读取。关于cacheType属性,参考API文档* ImageView也是四舍五入的,通常可以通过边框属性来设置。但是在安卓系统中,只有ImageView不能通过边框设置圆角,ImageView也有专有属性radius来设置安卓,未来可以改进。

5.处理右上角的添加按钮,然后点按弹出式菜单。

在处理click事件之前,请将右上角的ImageView的enable属性设置为true,并在chats/index.ui.js中添加代码

var add _ button=ui(' add _ imageview ');add_button.on('touch ',function(){ var menu=ui(' menu _ id ');If (menu) {//如果已经添加,就让这个视图显示,而不是添加一个新的If (menu。可见==假)菜单。可见=真;} else { main.add('menu_id ',' source ://view/chats/chat _ add _ menu . ui ');}});其中,chat_add_menu.ui是弹出菜单对应的ui文件。这个ui文件的根节点大小和chat/index.ui一样,保证了我可以通过点击任意空格来关闭这个菜单(实际上是隐藏了这个菜单)。我们在这个ui文件中拖放相应的布局,其中需要添加四个资源png文件。

这里有一个技巧。顶部的三角形标记只能通过ImageView加载一个三角形图标来实现。

然后,我们在chat_add_menu的根节点添加一个点击事件,点击时隐藏自己,在chat _ add _ menu.js中可以找到。

var root=ui(' $ ');root.on('touch ',function(){ root . visible=false;});最后我们先来看看真机效果,点击加号弹出菜单,点击任意位置隐藏菜单。

这部分暂时在这里。让我们开始拖放最后几个主页面。那些页面基本完成后,我们会再次回到这个页面进行阐述。

版权声明:JavaScript用DeviceOne开发实战(3)模仿微信应用是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。