1、互动点播系统设计与实现UI界面的设计与开发摘 要:近两年来,各式各样的网络电视盒子丰富了电视观众的选择,而各类中间件简化了电视盒子的程序开发,使得普通的程序员也可以在此平台方便的设计开发软件,以满足多样的需求。极大的市场潜力意味着有着大量的相应软件需求,通过设计开发互动点播系统,可以提前接触到这个流行的技术领域,对于我们了解有关电视盒子应用开发有极大的帮助。关键词:电视盒子;定制芯片;互动;中间件;服务器Abstract:In the past two years, all kinds of network TV box enriched TV audiences choice, and al
2、l kinds of the middleware simplifies the application development of TV box, make ordinary programmers can also in the platform software design and development, to meet the diverse needs.Great market potential means that there are a large number of corresponding software requirements, through the des
3、ign and development on demand system, can come into contact with the popular technology in advance, for us to understand about TV box application development is of great help.Key words:Custom chip box; interactive television; middleware; server1 UI界面的设计与开发1.1 编写目的UI是 User Interface,即用户界面的简称。而UI设计指的是
4、对软件的人机交互、操作逻辑以及界面的美观程度的整体设计。一个好的UI设计,不仅可以让软件变得更加有个性和品位,还有让软件的操作变得更加人性化,简单舒服的任务。UI设计大体包括:一,图形设计,即传统意义上的美工。二,交互设计,也就是软件的操作逻辑,操作流程之类的。三,用户测试,用来测试交互设计的合理性以及图形设计的美观性。所以这里,就从这三个方面来阐述UI界面的设计与开发。1.2 图形设计 UI界面设计的第一步,就是就是图形设计。我们的项目前端主要使用HTMl+CSS来实现效果呈现,所以在图形设计时候,主要使用PhotoShop来对图片进行切片和处理,用文本编辑器对图片进行排版设计。因为涉及到大
5、量重复的的图片处理步奏,我还特别为此用applescript编写了简易的图片批处理脚本,方便在PhotoShop上的处理,提高图片设计效率。使用PhotoShop,给我们进行图形处理提供了极大的帮助,PhotoShop的特点有一下这些:图1-1 在PS中进行图形设计图1-2 使用applescript编写的PS脚本1、像素层级的编辑像素是组成图片的最基本元素。Photoshop可以做到像素层级的编辑,功能强大。另外,除了编辑现有图片外,用户还可以用Photoshop制作图像,例如加入字体、向量图案等等。2、图层功能图层功能让图片既可以分层编辑,也可以合并图层进行统一修改。在同一个图层内,用户可
6、使用Layer Mask功能选取套用编辑的部分。3、动作功能动作功能可记录一连串的编辑动作,然后应用在不同图片中。当然PhotoShop的缺点也很明显:批量处理不方便。Photoshop单张图片的编辑处理功能比较强大,其本身也是为处理单张图片而设计。虽然可以使用camera RAW plug in来处理RAW文件,但Photoshop本身的批量处理功能并不算强大。所以针对这个缺点,我们根据实际需求,为其开发了简易的批处理工具,与PhotoShop相结合,就能很好的实现我们对于图形设计的需求了。第二步,为了在项目中使用设计好的图形,必须借助HTML+CSS来呈现效果。HTML指的是超文本标记语言
7、,标准通用标记语言下的一个应用。“超文本”就是指页面内可以包含图片、链接,甚至音乐、程序等非文字元素。超文本标记语言的结构包括“头”部分(英语:Head)、和“主体”部分(英语:Body),其中“头”部提供关于网页的信息,“主体”部分提供网页的具体内容。CSS指的是层叠样式表,是一种用来表现HTML或XML等文件样式的计算机语言。我们将图形放在HTMl的body里,用CSS来控制要呈现的效果,就能实现我们所需要的图形设计效果:-正在请求数据,请稍等!-节选片段选自项目首页的HTML代码块,是节目列表的图形设计与展示。第一行的“”表示以下模块代码行是属于节目列表功能的函数块。标签是层叠样式表中的
8、定位技术,用来为HTML文档内的内容提供结构和背景的元素。中的id是HTMl的选择器,id选择器允许以一种独立于文档元素的方式来指定样式,在这块代码中,我指定class为 poster0_img 的存放设计好的第一张图片,并在里赋予它CSS的属性,使图片对于页面相对定位,并规定内部包含的标签,确定图片的相对路径和相对位置。大量的图片都是通过这种方式定位在项目上,错综复杂的图片就构成了这个项目的图形设计。1.3 交互设计想要做好UI的交互设计,必须要求熟悉网站,能独立完成项目开发,网页设计和相关操作从事UI设计网站界面必须知道的知识。现场生产过程,例如,网站整体页面布局和网站知识的本质,能够满足
9、现场整体统一。设计一个网站并不仅仅是把信息,如图片和文本信息,音频和视频的页面如此简单,但是应该开始从用户的实用性,清楚的设计网站的性质,性质不同的设计风格,如政府机构是一个社会人们互相交流,信息公告,发布提供类网站,主要用于政府的公共可以学到一些重要的措施,重要的发布文档,和促进社会道德、伦理等等。1.3.1 交互设计技术介绍在该项目里面,我们主要使用JavaScript作为主要的交互设计语言,通过JavaScript来控制用户的的操作与实际函数的映射和逻辑的设计。JavaScript一种直译式脚本语言,是一种动态类型、弱类型、基于原型的语言,内置支持类型。它的解释器被称为JavaScrip
10、t引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HTML(标准通用标记语言下的一个应用)网页上使用,用来给HTML网页增加动态功能。JavaScript是一种属于网络的脚本语言,已经被广泛用于Web应用开发,常用来为网页添加各式各样的动态动能,为用户提供更流畅美观的浏览效果。通常JavaScript脚本是通过嵌入在HTML中来实现自身的功能的。1.3.2 交互设计功能思路由于本项目的运行平台是电视盒子,所以在用户实际运用时候,是通过遥控器而不是鼠标或者键盘对其进行操控。所以说,该项目的实际交互设计需要考虑的第一个因素就是如何模拟用户通过遥控器进行自然的操作,而不会感到不正常。第二个
11、因素是要贴合考虑到操作的方便性和合理性,让用户通过尽可能少的步奏操作,完成想要的动作。想要解决第一个问题,可以参考曾经智能DVD机的操作方式,观察他们的界面安排和操作方式,通过对比和学习,就可以摸索出一套比较通用的操作规范,不同于电脑端或者移动端的操作方式,只要将这套操作规范转换成实际的代码,就能顺利的实现模拟遥控器的操作方式。同时,我还将可能会用到的遥控器功能键以及与其对应的实际键值进行了搜集和整理。表1.1 遥控器按键与对应实际键值按键描述实际键值数字149数字250数字351数字452数字553数字654数字755数字856数字957数字048*(信息)848#(状态/输入法)572红8
12、32黄834蓝835绿833第二个问题,我们小组进过探讨和研究,决定使用当前社会上比较流行的栅格化原则来进行交互设计。我们的项目,规定了像素分辨率为1280*720。所以我们参照960栅格化系统的系统指定,设计出了1280栅格系统。通过这个1280栅格系统,就可以设计出同时具备方便性和合理性的交互逻辑,达到我们的目标预期。1.3.3 交互设计代码分析-function grdEvent(event)var keycode = event.which;Utility.println(listMovie grdEvent keycode=+keycode);switch(keycode)case
13、1:/ upcase 38:if(tipShowFlag | moreInfoShowFlag) return 0;if(area = 1)lastArea = area;changeArea(0);if(area = 2 & listPos 3)lastArea = area;changeArea(1);else if(area = 2 & (listPos = 3 | listPos = 4)changeListPos(-3);else if(area = 2 & listPos = 5)changeListPos(-1);else if(area =2 & listPos = 6)cha
14、ngeListPos(-4);return 0;break;-节选的函数grdEvent代码块主要负责接收用户所按按键的真实键值,并执行对应的响应函数。通过这个函数,用户每次按键之后想要的反应都会实时响应,达到用户的需求。下面具体介绍代码的功能实现:“var keycode = event.which;”底层硬件集成的中间系统会通过接收器接收到用户通过遥控器按下的键位,并将具体键值传递给event,并通过变量keycode接收。“Utility.println(listMovie grdkeycode=+keycode);”Utility.println方法可以将后面括号内的内容在串口输出打印
15、。接下来的switch(keycode).是编程语言经典的多分枝选择语句,准确的使用switch.case.语句能有效的避免冗长的if.elseif.else.代码块。圆括号内的keycode就是指前文所指的真实键值,通过一条条匹配对应键值的函数方法即可实现用户需求。代码块中出现大量类似if(tipShowFlag | moreInfoShowFlag) return 0;的语句,return 0的作用是跳出当前循环,而放在if()的后面意思就是当括号内成立时候,就跳出当前语句。作用就是在执行对应键值操作的方法之前先判断,当前状态是否不能响应这个动作,比如正在加载数据或者有上层panel覆盖的
16、时候,就不能响应确认按键的动作。如果不加这种判断,就很有可能出现逻辑错误,影响用户使用体验。这同时也是开发过程中最经常出现的问题之一,需要有清晰的思路已经多次的检查排漏才能确保不会出现此类问题。-function changePos(_num)if(area = 1)menuPos += _num;if(menuPos 6) menuPos = 0; $(focus).style.left = 99 + 158 * menuPos + px;else if(area = 0)lastPos = menuPos;menuPos += _num;if(menuPos 10) menuPos = 7
17、;$(lastPos).style.visibility = hidden;$(menuPos).style.visibility = visible; function changeArea(_area)area = _area;if(area = 0)if(lastArea = 1 | menuPos != 6)menuPos = 7;$(focus).style.visibility = hidden;$(menuPos).style.visibility = visible;else if(_area = 1)area = _area;$(focus).style.visibility
18、 = visible;if(lastArea = 0 & (menuPos = 7 | menuPos = 8)lastPos = menuPos;menuPos = 5;$(focus).style.left = 889px;$(lastPos).style.visibility = hidden;else if(lastArea = 2 & listPos = 2)lastPos = listPos;menuPos = 5;$(focus).style.left = 889px;$(List+lastPos).style.visibility = hidden;-节选代码块包含两个有关交互
19、设计的函数changePos和changeArea,从名字就可以很容易看出这两个函数是移动焦点位置和切换显示区域的函数。图2-1 用area来为项目划分区域我们的项目,是将页面分成多个区域,用area来区分。因为每个区域的交互逻辑都有不同,划分区域就可以清楚的将不同的逻辑代码放在不同的地方,一方面可以提高开发效率,减少开发时间。二是代码分离开,方便排查错误,这样当测试时候是在哪一区域出现逻辑交互错误,就可以快速定位代码位置,知道错误的大体位置。同理,在每个区域里的每个相对位置我们用XXXPos来表示,比如区域area0中有四个区域(搜索、收藏、历史、首页),于是我们就用menuPos0menu
20、Pos3来标示。这样,“if(menuPos 3) menuPos = 0;”就可以表示在循环中,如果当前焦点位置从第四个首页再往右移动,即munuPos=3再加1,就自动切换回最左边的搜索,即menuPos=0。这种切换方式代码量非常少,而且逻辑清晰,非常适合在我们这种简单的小程序里面使用。在项目中,大量这种类型的代码的调用,构成了项目最基础的交互移动系统,互相联系又不相互影响,强化了系统的鲁棒性。$().style.visibility = hidden和$().style.visibility = visible是通过html控制括号内对象类选择器的CSS。顾名思义可以看得出来,visi
21、bility指代的是对象是否可见。通过对其属性进行赋值hidden和visible,就可以轻松实现控制对象的出现和隐藏。如果同时让相邻的两个相同元素一个显示,一个消失,则可以出现仿佛是这个元素从一个位置移动到另一个位置的假象。这是一种编程的技巧,我们可以在每个焦点可能会移动的位置都事先隐藏一个焦点元素,这样,只要当系统监测到用户想要移动焦点位置的意图时候,通过hidden/visible的方法,就可以轻松实现。与之相对应的是$(focus).style.left = 396 + 150 * listPos + px;$(focus).style.top = 466px;这种方法,只生成一个焦点
22、元素,每次监测到用户移动焦点意图的时候,去计算焦点坐标变化,再让焦点移动到结束位置。这种做法需要在每次焦点移动时候做全面判断移动规则,然后用对应的变换函数去计算移动后的坐标位置。这两种做法优缺点非常明显。前者优点是没有任何延迟,在我们项目不支持多线程的硬件基础上,同时多个元素的移动不会出现卡顿或延迟的感觉,缺点就是前端页面代码比较冗长,每个对位都会嵌入同样的焦点图片标签。后者优点是前端代码清楚,只有一个个位置,没有大量重复的代码。但是缺点是后台逻辑部分有大量判断计算函数,而且开发难度较大,容易出现错误和bug。最佳的方法是两种相结合,移动规则单一且量大的时候用第二种方法,位置少但是移动不规律时
23、候后第一种方法。这样就可以很好的实现交互设计的需求了。1.4 总结网站界面的设计从以前的只重技术不重设计正逐渐改善为两者兼顾,设计的重要性和技术性是同等重要的。如果只重技术而设计的不好,那么即使技术性再强也达不到好的用户体验效果,从而不能满足一个网站总的功能的发挥,这样就影响了网站的价值,只有将技术性和设计效果结合起来才能达到更好的用户体验,更合理的人机交互,实现网站存在的价值。因此,网站界面的UI设计对于网站的建设非常重要。我们的项目很大程度是靠视觉呈现给用户使用与感受的,所以UI开发也是重中之重。前期我们做了大量的讨论与准备,研究过当前市场上比较流行的项目和开发方式,在开发中也是慢慢摸索,
24、常用的工具有如PhotoShop、HBuilder之类的都是在使用中渐渐熟悉的。不过,在探索和实践中,我们也深切体会到UI设计的重要性,同时也能感受到用户正真的需求,设计出最合适的交互方式,也为接下来的页面逻辑设计打好了基础。2页面逻辑的设计与实现2.1 编写目的逻辑设计就是把一种计划、规划、设想通过视觉的形式通过概念、判断、推理、论证来理解和区分客观世界的思维传达出来的活动过程。逻辑设计比物理设计更理论化和抽象化,关注对象之间的逻辑关系,提供了更多系统和子系统的详细描述。而我们的项目最终完成之后也是交由用户使用,一个完整且没错误的页面逻辑会是用户的使用体验达到完美,所以页面逻辑设计也是项目里
25、非常重要的一个部分,在本段会介绍我们项目主要页面逻辑的设计与实现。2.2 设计中的逻辑网格是用竖直或水平分割线将布局进行分块,把边界,空白和栏包括在内,以提供组织内容的框架的辅助性工具。设计中不能忽视的网格,从印刷物料到网页 页面,还是最新的Windows8系统界面,无论我们的设计如何,网格在设计中必然存在。网格可以使页面布局显得紧凑而且稳定,为设计师在设计站点时提供 一个逻辑严谨的模板。网格也可以使版式设计有连贯性和韵律,让那些看上去相当小并且毫无联系的元素也可以在网格的布局里占有自己的一席之地。但是网格不只是让设计师一味地按照规律来枯燥的设计,只是在一个合理的运用下构造和设计出好的作品来,
26、适时地打破规则也能有意外的惊喜。2.3 数据传递的逻辑设计我们项目的数据是通过HTTP的ajax与服务器进行交互,传递数据的格式主要由Xml转Json来进行。ajax是指一种创建交互式网页应用的网页开发技术。通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。传统的网页(不使用 AJAX)如果需要更新内容,必须重载整个网页页面。Ajax 的核心是 JavaScript 对象 XmlHttpRequest。该对象在 Internet Explorer 5 中首次引入,它是一种支持异步请求的技术。简而言之,XmlH
27、ttpRequest 使您可以使用 JavaScript 向服务器提出请求并处理响应,而不阻塞用户。Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE。URL全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上的资源,而HTTP中的GET,POST,PUT,DELETE就对应着对这个资源的查,改,增,删4个操作。到这里,大家应该有个大概的了解了,GET一般用于获取/查询资源信息,而POST一般用于更新资源信息。-function getlistProgData() listProgs = ;/clearListProgra
28、ms();if (listAjaxObj = null) listAjaxObj = new ajaxClass();listAjaxObj.frame = window; else listAjaxObj.requestAbort();$(loadingIcon).style.visibility = visible;listAjaxObj.successCallback = function(_xmlHttp, _params) var data = parseDom(this.getResponseXML();var jsonData = parseJson(data.toJson();
29、if (typeof(jsonData) != object | jsonData = null) $(listTips).innerText = 获取数据失败!;$(listTips).style.visibility = visible;if (!oneRequestFinish) oneRequestFinish = true;else $(loadingIcon).style.visibility = hidden;return; var key = FolderContents;if (key in jsonData) var totalResult = parseInt(jsonD
30、ata.FolderContents0.totalResults, 10);listServiceId = jsonData.FolderContents0.FolderFrame0.serviceId;listChargeMode = jsonData.FolderContents0.FolderFrame0.chargeMode;if (totalResult 0) /理论上来说应该没有电影返回,可以不用考虑。var series = jsonData.FolderContents0.ChildFolder;var movies = jsonData.FolderContents0.Sel
31、ectableItem;/添加一个属性标识是电视剧还是电影if (typeof series != undefined) for (var i = 0; i series.length; i+) seriesi.type = S; else series = ;if (typeof movies != undefined) for (var i = 0; i movies.length; i+) moviesi.type = M; else movies = ;listProgs = series.concat(movies);/hashTableObj.put(_params0, listP
32、rogs);currPage = Number(currPage);initListPrograms();$(listTips).style.visibility = hidden;$(loadingIcon).style.visibility = hidden;else if (NavServerResponse in jsonData) var message = jsonData.NavServerResponse0.message;var code = jsonData.NavServerResponse0.code;$(listTips).innerText = 发生错误!错误码:
33、+ code;$(listTips).style.visibility = visible;if (!oneRequestFinish) oneRequestFinish = true;$(loadingIcon).style.visibility = hidden;listAjaxObj.failureCallback = function(_xmlHttp, _params) $(listTips).innerText = 获取数据失败!;$(listTips).style.visibility = visible;if (!oneRequestFinish) oneRequestFini
34、sh = true;else $(loadingIcon).style.visibility = hidden;listAjaxObj.urlParameters = ;listAjaxObj.callbackParams = hashTableKey;listAjaxObj.url = http:/ + ip + : + port + /GetFolderContents, data/listProgData_ + menuType + _ + (currPage + 1) + .xmlDEBUG;listAjaxObj.requestData(POST);-这块引用的函数getlistPr
35、ogData代码块就是负责数据交互逻辑的函数。z在代码头定义的listProgs就是用来存放请求到的数据的数组。通过判断listAjaxObj是否为空来判断此页面是否为第一次加载数据,如果是第一次的话,将给他创建新的ajaxClass对象。ajaxClass对象就是像服务器请求数据用的对象。这是在函数的尾部,我们把要请求的数据拼接成xml的实现储存在listAjaxObj.urlParameters里,然后用POST的方式发往事先定义好的服务器位置。再根据组员的数据库设计,就可以在数据库里查找所需要的数据了。接下来就是通过判断是否请求成功转到成功或失败的回调函数里。回调函数就是一个通过函数指针
36、调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方法直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。因为可以把调用者与被调用者分开,所以调用者不关心谁是被调用者。它只需知道存在一个具有特定原型和限制条件的被调用函数。简而言之,回调函数就是允许用户把需要调用的方法的指针作为参数传递给一个函数,以便该函数在处理相似事件的时候可以灵活的使用不同的方法。在listAjaxObj.successCallback的成功回调函数内部,用data来接收返回数据,再通过da
37、ta.toJson方法将数据转成Json类型保存在jsonData里。再通过读取jsonDAta里面对应字段的内容判断请求到的是电影资源还是电视剧资源,并分别存放在series和movies里,最后拼接成listProgs的完整接收数据。因为格式统一,所以可以方便其他函数调用。而listAjaxObj.failureCallback则通过一系列的判断,得出请求失败的原因并附上对应措施,包括请求超时、请求资源为空、请求格式错误等一系列可能出现问题的情况。失败回调函数的作用在于一方面不会使得请求失败就处于卡死状态影响用户使用体验,另一方面也方便我们开发时候的调试工作,能够直观的看出问题出在哪个环节
38、,提高开发效率。-function initListPrograms() var srcPrefix = DEBUG = 0 ? (http:/ + ip + : + port + /) : ;for (var i = 0; i 5; i+) if (i listProgs.length) var posterUrl = ;if (typeof(listProgsi.Image) != undefined) for (var k = 0; k listProgsi.Image.length; k+) if (listProgsi.Imagek.width = 410 & listProgsi.Imagek.height = 543) posterUrl = srcPrefix + listProgsi.Imagek.posterUrl; $(p + i).src = posterUrl;var name = listProgsi.type = S ? listProgsi.displayName : listProgsi.titleBrief;$(lt + i).innerHTML = getStrChineseLen(name, 6);$(lt + i).style.background
©2010-2024 宁波自信网络信息技术有限公司 版权所有
客服电话:4008-655-100 投诉/维权电话:4009-655-100