原生开发

使用XML标签,Javascript和CSS来调用原生控件。

页面布局

单个页面通常由<title>, <header>, <content>, <footer>组成:

<?xml version="1.0" encoding="utf-8"?>   
<imag>   
    <page>   
        <title style="background:#999999">   
            <center><label>标题</label></center>   
        </title>   
        <header style="background:#cccccc;padding:10">   
            <label>顶部</label>   
        </header>   
        <content style="background:white">   
            <label>内容</label>   
        </content>   
        <footer style="background:#cccccc;padding:10">   
            <label>底部</label>   
        </footer>   
    </page>   
</imag>

<header>中的内容会始终显示在屏幕顶部,<content>是页面的主要内容,<footer>的内容在屏幕底部显示。

单行布局

<?xml version="1.0" encoding="utf-8"?>   
<imag>   
    <page>   
        <title style="background:#999999">   
            <center><label>标题</label></center>   
        </title>   
        <header style="background:#cccccc;padding:10">   
            <label>顶部</label>   
        </header>   
        <content style="background:white">   
            <row><label style="align:center">内容</label></row>   
        </content>   
        <footer style="background:#cccccc;padding:10">   
            <label>底部</label>   
        </footer>   
    </page>   
</imag>   

说明:<row>表示单行,将<label>放到<row>里,然后设置label的样式“align:center”,文字会居中对齐。
align的取值为left, center, right。
<row>控件的示例请参考:单行布局Row

列表布局

复杂的布局可以通过<list>来实现,如下面的例子:

<?xml version="1.0" encoding="utf-8"?> 
<imag> 
    <page> 
        <title style="background:#444444"> 
            <center><label>费用报销单</label></center> 
        </title> 
        <content> 
            <list type="group"> 
                <item> 
                    <col style="width:100"> 
                        <row><label style="color:gray">单据编号:</label></row> 
                    </col> 
                    <col> 
                        <row><label>BXD-08240250</label></row> 
                    </col> 
                </item> 
                <item> 
                    <col style="width:100"> 
                       <row><label style="color:gray">主题:</label></row> 
                    </col>                     
                    <col> 
                       <row><label>客户招待报销单</label></row> 
                    </col> 
                </item> 
                <item> 
                    <col style="width:100"> 
                        <row><label style="color:gray">职位:</label></row> 
                    </col>                     
                    <col> 
                        <row><label>财务总监</label></row> 
                    </col> 
                </item> 
            </list>  
        </content> 
    </page> 
</imag> 


其中:
<item>是列表项,每个<item>的都可以有自己的布局。
在<item>中,<col>表示一列,<row>表示一行。
<list>有点儿类似于HTML里的<table>,不同的是<table>是先有行<tr>再有列<td>,而<list>是先有列<col>再有行<row>。
在<col>上设置宽度style=“width:100”,未设置width的<col>会自适应宽度。
<list>控件的示例请参考:列表布局List

网格布局

<grid>以网格的形式来对内容进行布局,示例如下:

<?xml version="1.0" encoding="utf-8"?>
<imag>
    <page>
       <title>
            <center>
                <label>网格</label>
            </center>
        </title>
        <content>
            <grid>
                <item icon="tab_home_normal.png"><label>微信</label></item>
                <item icon="tab_category_normal.png"><label>通信录</label></item>
                <item icon="tab_service_normal.png"><label>发现</label></item>
                <item icon="tab_mine_normal.png"><label>我</label></item>
                <item icon="tab_home_normal.png"><label>微信</label></item>
                <item icon="tab_category_normal.png"><label>通信录</label></item>
                <item icon="tab_service_normal.png"><label>发现</label></item>
                <item icon="tab_mine_normal.png"><label>我</label></item>
            </grid>
        </content>
    </page>
</imag>
效果:

<grid>默认有3列,可通过cols属性来设置列数,如<grid cols=“4”>。
<item>是网格项,<grid>的每个<item>宽高都是相同的。
<grid>控件的示例请参考:网格布局Grid

标签页布局

<tabs>:以标签页的形式来进行应用布局。
标签页是移动应用上常用的布局方式,通过底部的标签按钮来切换不同的页面内容。
<tabs>控件的效果如下:


<tabs>控件的示例请参考:Tabs标签页

设置页面背景

在page上设置background样式,如:

<page style="background:white">
</page>
或者在content上设置background样式,如:
<page>
    <content style="background:white">
    </content>
</page>

设置按钮背景

在给按钮设置背景时可以设置按钮选中背景,如:

<button style="background:normal.png,pressed.png">按钮</button>
设计图片按钮时同时设计normal.png和pressed.png两个图片,用于点击时按钮状态的切换。
<button>控件的示例请参考:button

设置可拉伸的背景

有时候因为控件内容是动态变化的,我们需要设置可拉伸的图片背景,比如聊天消息的背景图片。
看一下这个例子:

<label style="background:chatfrom_bg_normal.png 50% 65%;padding:20 10 20 30;">移动互联网,就是将移动通信和互联网二者结合起来,成为一体。</label>
效果:

上面这个例子背景会随着文本的多少而变大,但不会变形和失真,这是因为背景图片是先切割之后再拉伸的。
这个背景图片的原图如下,大小为93×80:

label的样式设置了background:chatfrom_bg_normal.png 50% 65%,其中50% 65%是分别设置竖线和横线对图片进行切割,背景切割完再拉伸不会有失真。50% 65%换算成像素则分别为93*50%=47px和80*65%=52px,切割位置距左边和顶部分别为47px和52px,用百分比表示是为了适配不同屏幕分辨率的图片。

imag.js已经屏蔽了不同分辨率手机之间的差异,用imag.js开发的APP会自动适配不同手机。

长度适配

设置和长度相关的样式width,height,margin,padding时不带长度单位,如:style=“width:100”,而不要写成style=“width:100px”。

图片适配

图片适配用不同目录来对应不同的手机分辨率,服务器端图片资源目录结构如下:

Android图片资源目录是以屏幕密度(density)来区分,而iOS是以屏幕比例(scale)来区分。
anroid和ios目录下分别有一个default目录,当具体屏幕密度的图片找不到时会读取这个default目录中的相应的图片。
比如:<page style=“background:bg.png”>
对于Android屏幕分辨率为1080×1920的手机bg.png图片的目录查找顺序是:
/res/android/xxhdpi
/res/android/default
/res/default
对于iPhone7 Plus手机目录查找顺序是:
/res/ios/1242×2208
/res/ios/3x
/res/ios/default
/res/default
可以看到这个查找顺序是由内向外的。

在开发阶段,Android只用在/res/android/default放置xxhdpi(1080×1920)的图片即可,其余目录可以在APP打包发布时再放图片(也可以不放图片)。iOS需要/res/ios/default和/res/ios/3x下放置图片,其中/res/ios/default下放的是scale为2.0的图片(iPhone5, iPhone5S, iPhone6, iPhone7),/res/ios/3x下放的是scale为3.0的图片(iPhone6 Plus和iPhone7 Plus),其余目录可以不放图片。

Android各个屏幕密度的取值如下:

密度 ldpi mdpi hdpi xhdpi xxhdpi xxxhdpi
密度值 dip<140 140<dip<190 190<dip<280 280<dip<400 400<dip<600 600<dip
分辨率 240×320 320×480 480×800
480×854
720×1280 1080×1920 2160×3840
比例 3 4 6 8 12 24

可以根据比例来设计各种屏幕图片的大小:比如一个图片在hdpi上大小为48×48,那么在xhdpi上为64×64,在xxhdpi上为96×96(6:8:12)。

传递参数到下一页

传递参数到下一个页面将参数放到url里即可,如:

<list>
    <item href="nextpage.xml?username=Terry&amp;password=123"><label>下一页</label></item>
</list>
注意:因为href是XML的属性,多个参数用&amp;分割。(使用&会报错)

如果参数中含有汉字、空格等特殊字符,需要用encodeURIComponent()来对参数进行编码,如:
<list>
    <item onclick="$page.open('nextpage.xml?username=' + encodeURIComponent('用户名') + '&amp;password=123')"><label>下一页</label></item>
</list>
如果把$page.open()方法放到<script>标签里,因为有CDATA包裹,则不要把&转义成&amp;,参数之间用&分割,如:
<script>
<![CDATA[
    function openNextPage() {
        $page.open('nextpage.xml?username=' + encodeURIComponent('用户名') + '&password=123');
    }
]]>
</script>
<list>
    <item onclick="openNextPage()"><label>下一页</label></item>
</list>

获取参数值

在下一个页面通过$param[]数组来获取传递过来的参数值,如:

var username = $param['username'];
var password = $param['password'];
如果传递的参数有用encodeURIComponent()进行编码,则在获取参数时需要用decodeURIComponent()进行解码,如:
var username = decodeURIComponent($param['username']);
var password = $param['password'];

传递参数到上一页

传递参数到上一个页面需要使用$page.close()方法,因为只有当页面关闭的时候才能向上一个页面传递参数。这是因为移动设备上资源有限,手机上的页面都是基于栈的结构设计的,之前的页面都在栈里面,只有当前页面关闭的时候上一个页面才会激活。
传递参数到上一个页面的例子:

var users = 'Terry,Vic,Jack';
$page.close(0, 'setUsers("' + users + '")');
$page.close()提供了一个参数可以将当前页面的脚本字符串返回到上一个页面去执行。上面这个例子会关闭当前页,并执行上一页的Javascript中定义的setUsers()方法,通过回调的方式来向上一页传递参数。
具体示例请参考Page页面

在imag.js中通过$http.get()和$http.post()方法来获取后台数据,后台数据一般以JSON格式返回。 下面是一个简单的后台数据加载的例子:

<?xml version="1.0" encoding="utf-8"?>
<imag>
    <script>
    <![CDATA[
        function loadJSON() {
            $http.get('https://www.imagjs.com/download/data/example/message.json', function(data) {
                var obj = JSON.parse(data);
                $('message').text = obj.message;
            });
        }
    ]]>
    </script>
    <page>
        <title>
            <center>
                <label>异步加载JSON数据</label>
            </center>
        </title>
        <content>
            <button onclick="loadJSON();">加载</button>
            <label id="message"></label>
        </content>
    </page>
</imag>

后台接口返回JSON数据:
{"message":"Hello World!"}
上面的例子通过JSON.parse(data)将JSON数据转换成Javascript对象,然后在<label>中显示message的内容。

imag.js引擎自身已经做了大量的优化工作,比如对图片的优化(压缩和缓存)、对网络的优化、对内存的优化等,但我们在设计自己的应用的时候仍然需要注意一些问题。

● 页面打开的层次不要过深

进入页面的层次太深会导致打开过多的页面,前面的页面会占用大量的内存,可能会因为内存不足导致应用崩溃。 因此页面层次不要过深,同时浅层次的页面结构也便于直观地向用户呈现内容,提升用户体验。 打开的页面要及时关闭释放内存,从设计上保证应用的质量。

● UI控件不要嵌套过多

移动应用的UI都是由一个个的view(视图)组成的,view嵌套的层次过多会降低性能,同时可能会导致应用崩溃。

● 使用复用列表

在移动应用中view(视图)是很耗费系统资源的一个对象,过多的view(几千个)可能会引起内存不足而崩溃,同时一次性加载这么多view也会花费很长的时间。 但有时候就是有大量页面内容需要展示,比如说分页,比如说联系人列表。解决这一问题的方式是使用复用列表(reuse list), 它的原理是只创建一屏幕显示的view对象,当view被滚动超出屏幕之后就会被用来复用,因此只会占用一屏幕view的内存, 有效地解决了内存不足而引起崩溃的问题, 同时因为实际加载的view个数较少,具有很快的加载速度。 关于复用列表的使用具体请参考:List列表

● 使用离线缓存

使用离线缓存可以将已经下载过的页面内容缓存到手机本地,下次访问时从本地读取而不用访问网络,这样做可以很好地加快用户浏览速度,提升用户体验。 关于可以参考离线存储本地数据库, 至于缓存策略需要根据应用情况来具体设计。

  • development/advance.txt
  • 最后更改: 2018/12/13 16:17
  • 由 terry