AppCan開發框架詳細介紹

1UI2.0UI1.0的對比

2012年初,我們發佈了AppCan移動應用開發平臺,在這個版本中,我們內置了基於JQMobile方案的CSS UI框架。這個框架可以幫助開發者遵循一套規則下,快速的開發應用。這套方案中主要採用了組合的概念。例如對一個按鈕的描述,可以通過多個CSS類來組合進行定義,也可以通過視頻瞭解更多。
這樣通過不同的組合可以生成多變的效果。在實際商用應用開發過程中,它起到了幫助我們加快開發進度的作用。但是在開發過程中,我們還是遇到了一些問題,JQMobile CSS框架在這些問題上,表現得比較乏力:
1
1 自動填充寬度


上圖中同樣一個編輯框加上一個刷新按鈕的組合。在不同分辨率下,如果希望,刷新按鈕保持一個基本寬度,編輯框自動填充剩餘區域,在不使用JS的情況下是很難做到的,如果使用百分比控制刷新鈕的寬度,那麼在低分辨率和高分辨率之間將會有非常大的偏差。
1
2 類名稱過長
JQMobile
方案中,爲了幫助開發者能夠更直觀的瞭解代碼,每一個功能類的名稱都比較長。例如ui-page ui-mobile-viewport等。這造成了網頁代碼大小變大,降低了解析速度。
1
3 類功能拆分度低
JQMobile方案中,很多類定義,代碼重複較多,例如預製的多種色彩方案。同時由於拆分度低,經常需要重複定義類來覆蓋其他類中的屬性。
1
4 控件組合複雜
JQMobile
方案中,控件的實現代碼量很大,一個按鈕需要多個div span嵌套配合多個類才能實現。這造成開發中,界面代碼量增大,不好控制界面。

我們綜合各個項目中的開發經驗,整理彙總了AppCan UI2.0架構,它繼承了UI1.0的優點,並很好地解決了UI1.0的問題,可以使開發能夠更加的簡單。UI2.0框架圖如下:

上圖中,我們可以看到AppCan UI2.0框架在基礎的屏幕適配(RESOLUTION ADAPTER CLASS)基礎上,對元素基本屬性進行了拆分。通過如下步驟來設定一個元素。
   定位-對元素進行佈局,確定元素的現實位置大小等[LAYOUT CLASS]
   描邊-對元素基礎屬性進行設定,例如邊框圓角等
[BASE CLASS]
   添色-對元素的邊框、文字和背景進行設定
[COLOR CLASS]
   插圖-如果元素中需要圖片,從資源中引入圖片類
[RES CLASS]

基於基礎元素之上,爲了方便開發者,我們重新定義了控件,包含BUTTONLISTFOLDINPUTTABRADIOCHECKSWITCH。這些控件可以認爲是UI2.0框架的具體事例。通過UI2.0完成的控件,代碼大小和複雜度,都有明顯的降低,如下例:


UI1.0
框架實現的按鍵

<div class="ui-btn ui-corner-all ui-shadow ui-btn-b"> 
  
<span class="ui-btn-inner ui-corner-all">
  <span class="ui-btn-text ">確定
</span>
</span>
</div>


UI2.0
框架實現的按鍵

<div class="btn btn-act ubb uc-t1 b-bla uinn c-blu2 c-m4 ">確定 </div>

從上述代碼中可以看到,同樣功能和效果的控件可以減少三分之二的代碼,嵌套減少到一層,代碼複雜度極大降低。
接着我們詳細介紹如何使用UI2.0框架。

2UI2.0框架的設計來源——彈性盒子模型

彈性盒子模型是CSS3.0推出的一種佈局機制。這種機制與常見的流式佈局有很大區別。簡單的理解爲,流式佈局是通過內容決定父容器大小,彈性盒子模型是,在指定大小的父容器裏來爲子元素分配空間,簡單的流式佈局例子。
效果:

代碼:

<div style="display:inline;border:1px solid blue">
  
<div style="display:inline;background:#E00">aaaa </div>
  
<div style="display:inline;background:#0E0">bbbb </div>
</div>

上述代碼中是一個簡單的流式佈局範例,第1行的div的寬度,是由第2和第3行的div寬度相加來決定的。即如果第2行或第3行的div寬度變化,第1行的寬度也會隨之變化。我們調整一下代碼,使用彈性盒子模型來佈局。
效果:

代碼:

<div style="display:-webkit-box;width:200px;border:1px solid blue">
  
<div style="-webkit-box-flex:1;background:#E00">aaaa </div>
  
<div style="background:#0E0">bbbb </div>
</div>

上述代碼中,指定第1行的div使用BOX方式佈局子元素。並指定這個div200px。第3行的div的寬度由內容撐開,可以認爲是一個指定寬度的div,通過模擬器可以看到寬32px。第2行指定這個div爲彈性,佔用1份空間,就代表這個div的寬度是總寬度200px-32px=168px。如果我們改動第1行的div寬度爲320px,那麼第2div的寬度就是 320px-32px=288px。這個機制對於適配各種分辨率的屏幕無疑是一把利器。
我們再調整一下代碼。
效果:

代碼:

<div style="display:-webkit-box;width:200px;border:1px solid blue">
  
<div style="-webkit-box-flex:1;background:#E00">aaaa </div>
  
<div style="-webkit-box-flex:2;background:#0EE">bbbb </div>
  
<div style="background:#0E0">cccc </div>
</div>

我們加入了一個佔用2份空間的div。這個時候這兩個彈性DIV到底如何分配空間呢?按照規則來說,第2行應該佔用168px/3=56px,第3行佔用112px,但實際上寬度並不是如此,通過模擬器可以看到,第34行佔用66px,第35行佔用102px。這是由於當彈性DIV中有內容時,引擎會自動進行調整。那麼如何在有內容的情況下還能夠保持12的比率呢?我們再調整一下代碼。
效果:

代碼:

<div style="display:-webkit-box;width:200px;border:1px solid blue">
<div style="-webkit-box-flex:1;background:#E00;position:relative">
 
<div style="position:absolute;width:100%;height:100%;">aaaa </div>
</div>
<div style="-webkit-box-flex:2;background:#0EE;position:relative">
<div style="position:absolute;width:100%;height:100%;">bbbb </div>
</div>
<div style="background:#0E0">cccc </div>
</div>

這次修改中,我們把內容"aaaa"通過一個使用絕對定位的div進行包含,這時通過模擬器去看會發現,兩個彈性div按照1:2的比率自動分配了空間。上面我們使用彈性盒子佈局時元素都是橫向排序的,那麼怎麼才能讓元素縱向排布呢。我們接着調整一下代碼。
效果:

代碼:

<div style="display:-webkit-box;height:200px;border:1px solid blue;-webkit-box-orient:vertical;">
<div style="-webkit-box-flex:1;background:#E00;position:relative">
 
<div style="position:absolute;width:100%;height:100%;">aaaa </div>
</div>
<div style="-webkit-box-flex:2;background:#0EE;position:relative">
<div style="position:absolute;width:100%;height:100%;">bbbb </div>
</div>
<div style="background:#0E0">cccc </div>
</div>

上述代碼中,我們在第1行的div中指定了高度爲200px,使用-webkit-box-orient:vertical來控制子元素爲縱向排列。
彈性盒子模型還提供了其他幾個強大的屬性。
 -webkit-box-direction:reverse;
通過在父DIV中設定這個屬性可以讓子元素反向排列。如下圖:

使用前子元素按照1 2 3 的順序進行排列顯示,當在父DIV中使用此屬性時,自動把子元素倒序排列。這個時候,我們並沒有真的重新按照3 2 1順序排布子元素。
 -webkit-box-align:center;
通過在父元素中設定這個屬性,當子元素橫向排布時,可以使子元素間實現上邊界對齊、中線對齊和下邊界對齊的效果

如果是縱向排列時,那麼可以實現子元素左邊界對齊、中線對齊和右邊界對齊。

 -webkit-box-pack:center;
通過在父元素中設定這個屬性,當子元素橫向排布時,可以使子元素間左邊界對齊、中線對齊和右邊界對齊

如果是縱向排列時,那麼可以實現子元素間上邊界對齊、中線對齊和下邊界對齊的效果。

如果父元素中只包含一個子元素,混合使用-webkit-box-align -webkit-box-pack可以使子元素實現居左上、居中上、局右上等9個方位的定位。
彈性BOX架構可以同時兼容流式佈局,即當所有子元素都沒有設定彈性份數時,父元素可以被子元素自動撐開。如下代碼
效果:

代碼:

<div style="display:-webkit-box;border:1px solid blue;-webkit-box-orient:vertical;">
  
<div>aaaa </div>
  
<div>bbbb </div>
  
<div>cccc </div>
</div>

在上述代碼中所有子元素都未使用box-flex定義彈動屬性,容器div也未設定高度,此時,容器div的高度爲三個子元素的高度和,並且隨着子元素的高度變化而變化。
AppCan UI2.0架構中,我們把上面遇到的情況進行了CSS類封裝
● ub
元素採用彈性BOX佈局
● ub-rev
子元素反序排列
● ub-con
在子元素中加入一個容器,用於避免內容引起子元素大小變化。
  對應CSS代碼爲position:absolute;width:100%;height:100%;
● ub-ac
ub-ae 子元素垂直居中對齊和尾對齊

● ub-pc
ub-peub-pj 子元素水平居中對齊、尾對齊和兩端對齊
● ub-ver
子元素縱向排列
● ub-f1 ub-f2 ub-f3 ub-f4
子元素佔用區域份數
通過上述類,我們可以完成各種各樣的排版佈局,極大地降低學習難度和元素排版複雜度,使代碼更加簡練。

32UI2.0框架開發指南

3.1 基石 (UI的分辨率適配)

  每一個手機應用,如果需要在衆多的移動終端上保持一致的效果,UI適配是工作的重中之重。UI2.0框架與UI1.0框架在屏幕適配機制這一部分依然保持一致。設計原理是爲不同分辨率的系統,選取最貼近於人直觀感受舒適度的一個字體大小作爲參考量。例如在320x480分辨率的手機上,採用16px大小字體作爲參考量。在480x800分辨率的終端上,採用24px大小字體作爲參考量。一切元素的大小都是以參考量的相對比值來定義。在CSS裏面對應的是em。那麼在320x480分辨率下 1em=16px,在480x800分辨率下1em=24px。 
  通過這種方式,我們可以保證,同樣代碼的界面,在不同分辨率下都能夠保持最貼近用戶的交互效果。
  在UI1.0中,我們在HTML文件中引用ui-media.css,即可處理當前常見分辨率的適配。但是由於各手機平臺不同,和各種新分辨率手機的問世,都對適配工作提出了更高的要求。
  UI2.0中,我們在中間件中爲不同屏幕密度(單位尺寸中可顯示的點數),默認定義好了字體,開發者不再需要在代碼中引入ui-media.css文件,即使有新的分辨率手機問世,也會自動適配。目前參照Andorid屏幕密度劃分爲低密度、普通密度、高密度、超高密度,分別定義字體爲14px 16px 24px 32px

3.2 骨架(元素佈局與定位)

在選定好的基石之上,我們需要爲我們的目標界面,搭建骨架。骨架從構建上可以分爲主幹和旁支。
主幹
主幹可以認爲是整個頁面的整體框架佈局

上圖是截取與ZAKER(原生開發)、正益無線(HTML5開發)ZAKER微博界面(原生開發)HTML5中國(HTML5開發)。參考上述界面我們看到大部分應用的頁面都遵循標題+內容+底部欄的佈局方式。AppCan UI2.0提供了簡單的佈局架構模板來適配這種佈局。Demo007範例下載

模板代碼中我們可以看到默認存在index.htmlindex_content.html兩個文件。我們通過對這兩個文件的分析來講解AppCan UI2.0推薦的應用開發模式。index.html文件分爲三部分HEADBODYSCRIPT
HEAD
部分:

<head>
<title></title>6
<meta charset="utf-8">
<meta name="viewport" content="target-densitydpi=device-dpi, width=device-width, initial-scale=1, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"<
<link rel="stylesheet" href="css/ui-base.css">
<link rel="stylesheet" href="css/ui-box.css">
<link rel="stylesheet" href="css/ui-color.css">
<link rel="stylesheet" href="css/ui-res.css">
<script src="js/zy_control.js">
</script<
<script src="js/zy_click.js">
</script>
</head>

這一部分定義了網頁引用的CSSJS文件。上面代碼中ui-base.css代表基礎類文件,ui-box.css是彈性盒子封裝類文件,ui-color是色彩基礎類文件。zy_control.js是默認控件和網頁需要的一些默認功能支持類。zy_click.jsClick事件模擬類,用於替代默認的onclick事件(手機中onclick響應較慢使應用體驗性差)
BODY
部分

<body class="um-vp c-wh" ontouchstart>
 
<div id="page_0" class="up ub ub-ver" tabindex="0">
<!--header
開始
-->
 
<div id="header" class="uh c-org c-m1 t-wh">
 
<h1 class="ut ulev0 ut-s tx-c" tabindex="0">AppCan</h1>
</div>
<!--header
結束--> <!--content開始
-->
 
<div id="content" class="ub-f1 tx-l t-bla ub-img6 res10">
</div>
<!--content
結束--> <!--footer開始
-->
 
<div id="footer" class="uf c-m2 c-bla t-wh">
 
<h1 class="ut ulev-2 tx-c" tabindex="0">(c) Copyright 3G2WIN and others 2011.
<br>
All rights reserved. </h1>
</div>
<!--footer
結束
-->
</div>
</body>

Body部分定義了一個頁面page_0,這個頁面的高度爲屏幕高度(up),使用彈性盒子佈局(ub),它的子元素縱向排列(ub-ver)。這個頁面中包含headercontentfooter三個區域。
header
footer部分是一個DIV,是一個定高的區域(通過內容撐開)content是一個彈性區域,它會佔滿page_0中除了headerfooter外的區域。如果headerfooter的高度變化,content的高度也會隨之變化。但是這種佈局當內容區域有內容時會引起整個content的高度撐高,由於大部分移動終端都不支持DIV的內部區域滾動,這回造成整個頁面能夠被拖動,這是與我們要求不符的。我們通過SCRIPT區域的代碼來處理這個問題。
SCRIPT
部分:

<script>
zy_init();
window.uexOnload = function(type){
if (!type) {
zy_con("content", "index_content.html", 0, $$("header").offsetHeight);
}
window.onorientatiοnchange=window.οnresize=function()
{
zy_resize("content",0,$$("header").offsetHeight);
}
}
</script>

上述代碼中zy_init函數用於在模擬器中實現字體的自動適配。在手機中無作用。
window.uexOnload
事件用於在AppCan中間件擴展對象加載完成後調用。在這個函數裏,我們調用了封裝在zy_control.js裏的zy_con函數創建了一個浮動VIEW。這個Viewcontent的區域保持同樣的大小,位置也與content區域的位置保持相同。這個View顯示的內容來自於index_content.html頁面。也就是說,我們的index.html頁面中content區域其實並不包含內容,它只起到一個定位的作用,爲浮動View提供定位支持。
window.onorientatiοnchange=window.onresize
這行代碼爲iOSAndorid平臺的屏幕旋轉事件指定了回調函數,當發生屏幕旋轉時,會調用這個函數,此時我們調用封裝的zy_resize接口參照content區域的新的高寬位置重新定位了浮動窗口。
更方便的是,開發者可以爲content區域開發不同的content頁面,可以根據的操作隨時使用zy_con接口變更content區域的頁面內容來實現不同的功能。例如可以配合下方的導航條控實現功能切換。

AppCan UI2.0框架推薦這種方式來編寫頁面,相對於UI1.0框架來說,處理邏輯更加簡單,適配更加方便,並且在一個窗口中,並不是只允許包含一個浮動窗口,我們可以創建多個浮動窗口來完成不同的功能,輕鬆的實現功能的拆分,減少在一個頁面中實現衆多功能引起的邏輯問題。同時這種方式可以輕鬆的實現固定的背景圖片。上述代碼中,我們看到我們爲content區域指定了一張背景圖,而我們在index_content.html沒有指定背景色,這樣顯示index_content.html網頁時會顯示出蓋在在下方的content區域。由於浮動窗口是獨立的窗口,因此它的頁面滾動並不會影響下方content區域。當然這種佈局我們使用iscrollJS包也可以很方便的實現,但是在很多Android手機上,由於性能原因體驗相對於原生應用還是會有很大差距。
AppCan UI2.0
框架支持浮動窗口的彈動效果,開發者可以很方便的實現彈動效果,在index_content.html中我們已經默認提供了範例代碼。接着我們看一下實際的內容區域網頁index_content.html。這個頁面與index.html一樣同樣分爲三個部分HEADBODYSCRIPTHEAD部分與index.htmlHEAD部分一樣沒什麼區別。BODY部分開發者可以根據需求添加列表、表單、地圖等功能實現。SCRIPT部分的代碼我們看一下:

<script>
zy_init();
window.uexOnload=function(type)
{
if(!type){
uexWindow.setBounce("1");
uexWindow.showBounceView("0","#FFF","0");
uexWindow.showBounceView("1","#FFF","0");
}
}
</script>

上述代碼中zy_init()用於在模擬器狀態下實現字體自適配,手機上無作用。uexOnload事件定義了浮動窗口AppCan擴展加載後的回調函數。當加載成功後,我們會調用AppCan彈動接口爲浮動窗口添加彈動效果,並設定彈動背景色。大家可以使用範例應用來體驗一下。
旁支
在完成頁面後,我們需要對頁面中的元素進行佈局。使用彈性盒子,將使這個佈局工作的難度降低很多。我們定一個目標,如下圖

我們可以對他進行如下區域劃分。

 左側定寬圖片區域
  圖片子區域
右側文字區域
  文字正文區域
  文章屬性區域
我們在index_content.html種進行佈局,代碼如下
效果:

代碼:

<div οnmοusedοwn="zy_touch('btn-act')" class="ubb ub b-gra t-bla lis">
<div class="lis-th ub-img im">
<div class="ub-f1 ub ub-ver">
<div class="ulev1"><
標題名
>
<div class="ulev-1 umh4 t-gra">
文本說明
</div>
<div class="ub ub-ac t-gra ulev-2">
<div class="umh2 umw2 ub-img " style="background-image:url(css/img/icon1.png);">
<div class="ub-f1">
收藏數
</div>
<div class="umh2 umw2 ub-img " style="background-image:url(css/img/icon2.png);">
<div class="ub-f1">
評論數
</div>
</div>
</div>
</div>

上述代碼中,我們首先定義了一個容器,通過class="ubb ub b-gra t-bla lis"設定容器的下邊框爲灰色(ubb b-gra),文字色爲黑色(t-bla),容器採用彈性盒子佈局(ub),容器是一個list條目(lis)然後我們在容器中構建了一個縮略圖元素class="lis-th ub-img im",指定了縮略圖大小(lis-th),定義了縮略圖的顯示方式(ub-img)和縮略圖圖片資源(im)。由於圖片區域定寬,文字區域是彈性的,因此我們爲文字區域構建了容器ub-f1 ub ub-ver,容器寬度爲彈性(ub-f1),容器也採用彈性盒子佈局(ub),容器中的元素採用縱向佈局(ub-ver)。我們分別在容器中加入標題、文本說明。收藏評論欄我們認爲又是一個容器,這個容器中的字元素採用橫向佈局。我們在其中加入兩個小圖片和兩段文字收藏數評論數。到此我們就完成了這個界面的佈局。
這個例子只是一個簡單的佈局應用範例,通過這個例子來展示,AppCan UI2.0在佈局頁面時的簡便性。

3.3 皮膚-元素的美化

當我們爲一個元素設定完佈局和位置後,接着就是要對這個元素進行美化。使人舒服的外表是吸引使用者的重要因素。AppCan UI2.0框架中對一個元素的效果屬性分化爲幾類,通過這些不同類別屬性的組合來完成對元素UI的設定。

大小位置形狀控制
 圓角類別: uc-{類型}[類型] [類別]
 
uc-tl, uc-tr, uc-bl, uc-br , uc-t, uc-b, uc-r , uc-l, uc-a, uc-n, uc-tl1, uc-tr1, uc-bl1, uc-br1, uc-t1, uc-b1, uc-r1, uc-l1, uc-a1, uc-a2, uc-a3
 陰影類別: us [類別]us-i [類別
]
 
us,us1,us-i
 比例類別:ulev[類別](由於元素的控制主要通過em來進行相對控制,ulev可以對默認比率進行放大縮小
)
 
ulev2,ulev1,ulev0,ulev-1,ulev-2 
 浮動類別: ufl
ufr
 限寬類別
: ulim
 單行類別
: uinl
 邊距類別: uinn[類別
]
 
uinn,uinn1,uinn2,uinn3,uinn4 
 最小高寬類別: um{wh}[類別
]
 
umh1,umh2,umh3,umh4,umh5,umh6,umw1,umw2,umw3 
 文字對齊類別:tx-{類型
}
 
tx-l,tx-r,tx-c 
 文字縮略類別
:ut-s
 邊框類別:ub{類型}[類別
]
 
ubt,ubb,ubr,ubl,uba,uba1,uba2
 隱藏類別
:uhide
 間隔類別:umar-{類型
}
 
umar-b
色彩控制

UI2.0
框架對元素的色彩劃分爲邊框色、文字色、背景底色和背景遮蓋層
 背景遮蓋類別: c-m{類別}
 
c-m1,c-m2,c-m3,c-m4,c-m5,c-m6,c-m7
 背景底色類別: c-{色彩}[類別
]
 
c-blu,c-blu1, c-blu2, c-blu3, c-blu4,c-wh, c-bla,c-gra,c-gra1,c-gra2,c-gre,c-red,c-yel
 文字色類別:t-{色彩}[類別
]
 
t-bla,t-wh,t-gra,t-blu
 邊框色類別:b-{色彩}[類別
]
 
b-bla,b-wh,b-gra,b-gra1,b-blu
資源控制

UI2.0
框架一些常用圖片資源進行了定義。例如搜索圖標等。
 資源類別:res{類別}
 
res1,res2,res3,res4,res5,res6,res7,res8,res9,res10
AppCan UI2.0
框架對一個元素的基礎屬性進行了拆分整理,通過不同的組合來定製元素效果,同時這個方案也是一種規則,開發者可以根據具體的實際情況在對應的類別中擴展自己需要的特效。遵循這個規則可以提高代碼的可重複利用率和維護管理效率,避免團隊開發中由於各種自定義類別混亂定義引起的UI適配和維護問題。同時使用UI2.0框架構建的控件,代碼量將會極大地減少。下面一節我們將對各種常用在應用中的控件的實現來使大家瞭解UI2.0UI實現上的巨大優勢。

4UI2.0中的控件

4.1 按鈕

上面圖片展示了一些按鈕的效果,我們通過代碼看一下IDE是如何使用基礎類來定義這些按鈕的。我們選擇index_content.html,在其Body區域添加一個按鈕。在AppCan IDE(UI2.0)中,我們選擇中標紅的按鈕,進入按鈕製作嚮導。

在上面這個界面中,我們可以選擇建立普通按鈕、帶圖標按鈕和特殊定義按鈕例如iOS效果按鈕等。一般情況下按鈕會佔滿整個容器,選擇內聯可以使按鈕和其他控件在不超出容器寬度的情況下保持在同一行。如果按鈕在標題或頁腳中,可以選擇居於左側或右側。高級模式可以對按鈕的顯示效果進行配置。

上面的界面中,我們可以配置按鈕的圓角、邊框、邊框色、背景色和背景遮蓋漸變色。這些效果不光是對按鈕起效,對於其他控件也是同樣的定義。這裏定義的效果只是我們預置的效果,開發者如果需要定義自己的色彩時,只需要在ui-color.css中添加自己的類定義後,對代碼中的默認顏色類進行替換即可。我們添加一個深藍色的按鈕。
效果:

代碼:

<!--按鈕開始-->
<div ontouchstart="zy_touch('btn-act')" class="btn uba1 b-bla uinn5 c-blu c-m1 uc-a t-wh">
確定
</div>
<!--
按鈕結束-->

首先使用btn來定義這個DIV是一個按鈕(我們爲不同控件類型定義了一個標識類,用於定義一些此類控件通用的屬性)。然後使用uinn5在文字外定義了一個內邊距,這樣按鈕的高度就是內邊距+文字高度。使用uc-a定義按鈕四個圓角都爲0.6em。接着我們使用c-blu指定背景色爲藍色。在通過c-m1在藍色上加了一層漸變遮蓋層。使用t-wh定義文字爲白色。
最後我們通過uba1指定邊框所有邊都爲2px寬,並通過b-bla設定邊框色爲黑色。到此就完成了一個按鈕在不點擊狀態下的效果。相對於之前UI1.0中一個普通按鈕需要一個DIV和兩個SPAN的嵌套要簡化了2/3的代碼,層次也減低到一層。現在我們爲這按鈕加上點擊效果。按照標準CSS3來說,只需要使用僞類:active來設定一個類即可完成鼠標按下彈起的效果變換,但很遺憾,在Andorid平臺,這個效果大部分手機支持的都有問題。對於iOS平臺這個屬性是支持的,但是如果想使這個僞類有效,則必須在代碼中加入ontouchstart,才能夠激活這個僞類。爲了解決這個跨平臺問題,我們提供了zy_touch接口,通過這個接口,它可以完成點擊效果的處理。
這段代碼中,我們加入了ontouchstart="zy_touch('btn-act')"zy_touch是封裝在zy_control.js中的擴展函數,btn-act是我們預定義的一個通用控件點擊凹陷效果類。通過這個函數,我們構建了一個點擊監聽類zyClick(如果使用zy_touch還需要引用zy_click.js),他會監聽觸摸屏事件,來控制爲按鍵增加和去除點擊效果,同時可以判斷是否爲點擊操作,如果判定成功,會直接調用參數中的回調函數來達到onclick事件的效果,可以解決手機瀏覽器中onclick不靈敏的問題。同時zy_touch還支持直接調用HTML代碼中的onclick屬性實現點擊效果。我們調整代碼
代碼:

<!--按鈕開始-->
<div ontouchstart="zy_touch('btn-act')" οnclick="alert(1)" class="btn uba1 b-bla uinn5 c-blu c-m1 uc-a t-wh">
確定
</div>
<!--
按鈕結束-->

上述代碼中我們可以看到,我們註冊了onclick函數,zy_touch會直接截獲onclick事件,代替系統調用onclick代碼,而不會調用兩次onclick。這種寫法更貼近於開發者正常應用的寫法。另外,由於目前模擬器中還不支持ontouchstart事件,因此上述代碼ontouchstart不會被執行,模擬器重看不到點擊效果,但onclick函數還是會被調用。
如果希望在模擬器上看到效果,可以替換ontouchstartonmousedown。雖然手機中也支持onmousedown事件但是他的效果和時序和touch事件有差別,因此我們在手機中運行的時候還是要替換回ontouchstart
上面的按鈕是使用DIV實現的,而DIV默認是一個塊。因此會佔滿整個寬度。如果需要使按鈕與其他控件在同行顯示,我們需要爲齊添加uinl類。
效果:

代碼:

<!--按鈕開始-->
<div ontouchstart="zy_touch('btn-act')" οnclick="alert(1)" class="btn uba1 b-bla uinn5 c-blu c-m1 uc-a t-wh uinl">
確定
</div>
<!--
按鈕結束-->

我們可以看到按鈕的寬度已經不是整行顯示而是根據按鈕中的文字寬度、邊框寬度、內邊距寬度來展現。需要注意的是,uinl會和ub有效果衝突,在彈性盒子模型中,子元素需要處於塊模式(display:block)。剛纔介紹的是一個最簡單的按鈕,好我們現在爲按鈕增加一個圖標。在IDE中選擇按鈕嚮導,在按鈕類型中,選擇帶圖標按鈕。同樣配置爲深藍色。
效果如下:

代碼:

<!--按鈕開始-->
<div ontouchstart="zy_touch('btn-act')"class="btn uba1 b-bla c-blu c-m1 uc-a ub t-wh uinn5 ub-ac">
<div class="ub-f1 ut-s">
確定
</div>
<div class="umh1 umw1 ub-img res1 c-bla uc-a"></div>
</div>
<!--
按鈕結束-->

無圖標的按鈕中,我們直接在DIV中加入了文字。這次因爲有圖標我們認爲按鈕中分左右兩個區域,左側文字區域自動適配寬度,右側圖標區域寬度固定。文字和圖標中線對齊。首先我們定義按鈕的外部效果class="btn uba1 b-bla c-blu c-m1 uc-a ub t-wh uinn5 ub-ac",這個與之前的按鈕無區別,唯一添加的是 ubub-ac分別代表子元素採用彈性盒子佈局,子元素中線對齊。我們爲文字區域設定了彈性寬度(ub-f1),並指明當文字超出容器寬度時,自動縮略不換行(ut-s)。最後我們定義了一個圖片,這個圖片高(umh1)(umw1),採用ub-img控制其縮放,res1代表箭頭圖片,c-bla代表圖片區域默認背景色,uc-a使其有圓角,由於圖片寬度較小,配合圓角使其象一個圓形。這就是用彈性盒子佈局定義的一個帶圖標按鈕。那麼如何使圖標居於左側呢?彈性盒子模型的便利性在這裏有很好的體現。我們在容器中加入ub-rev類,它設定子元素反向排序,很簡單實現圖標居於左側。

<!--按鈕開始-->
<div ontouchstart="zy_touch('btn-act')" class="btn uba1 b-bla c-blu c-m1 uc-a ub t-wh uinn5 ub-ac ub-rev">
<div class="ub-f1 ut-s">
確定
</div>
<div class="umh1 umw1 ub-img res1 c-bla uc-a"></div>
</div>
<!--
按鈕結束-->

那如何使圖標上下佈局呢?一樣很簡單,只需要在容器中加入ub-ver,定義容器中的子元素縱向排序即可。

<!--按鈕開始-->
<div ontouchstart="zy_touch('btn-act')" class="btn uba1 b-bla c-blu c-m1 uc-a ub t-wh uinn5 ub-ac ub-ver">
<div class="ub-f1 ut-s">
確定
</div>
<div class="umh1 umw1 ub-img res1 c-bla uc-a"></div>
</div>
<!--
按鈕結束-->

通過上面的例子可以看到其實一個按鍵就是一個容器加一些子元素進行彈性盒子佈局,然後爲容器和子元素加一些控制和顯示效果。而其他控件也是這種方式,只是顯示效果定製上稍有不同罷了。

4.2 容器

UI2.0中我們認爲所有控件其實都是容器塊配合子容器和子元素組合。因此,容器是我們最基礎的組件之一。在應用開發中,經常需要把幾個按鈕、複選框或其他控件合併成一組進行顯示。在這種情況下一個滿足效果的容器將是必不可少的。我們接下來將講解,如何利用AppCan來構建一個容器並按照我們的想法對元素進行排列打開AppCan IDE(UI2.0),我們選擇中標紅的按鈕,進入容器製作嚮導。

可以看到容器分爲縱向排列容器和橫向排列容器。默認容器中會建立三個子元素,如果用戶需要自己控制子元素的話可以選擇無條目來建立一個空的容器。同時與按鍵控件相同,我們可以很簡單爲容器指定各種效果。我們接下來通過範例來演示如何使用容器。這次的範例是一個登陸的頁面

這個頁面中,縱向排列的兩個編輯區域用來演示縱向排列容器。兩個按鈕用於演示橫向排列。首先此頁面高度不會超過一個屏幕,因此我們不需要實現頁面的拖動。因此不需要建立一個浮動View來顯示內容區域,而可以直接在內容區域添加代碼。Demo008爲此範例的初始界面。我們在此基礎上進行調整來完成登陸頁面。Demo008範例首先在插入編輯區域和按鈕區域前,我們先對內容區域進行調整。content區域調整後的代碼

<div id="content" class="uinn2 c-org1 ub-f1"></div>

上述代碼中我們爲內容區域設定了橙色背景(c-org1),彈性區域(ub-f1)自動適配屏幕,最後設定其內邊距(uinn2),這樣可以使後面我們將要添加的元素不會緊貼內容區域邊界。準備完成後,我們在頁面中添加一個縱向排列容器。

<!--塊容器開始-->
<div class="ub ub-ver uba b-gra uc-a1 t-wh ">
<div class="ubb b-gra c-blu c-m1 uinn uc-t1">
條目
1</div>
<div class="ubb b-gra c-blu c-m1 uinn ">
條目
2</div>
<div class="c-blu c-m1 uinn uc-b1 ">
條目
3</div>
</div>
<!--
塊容器結束-->

我們構建了一個默認的帶三個條目的縱排塊容器。由於此範例中只需要兩個條目,且背景爲統一的白色背景,因此我們需要對生成的代碼進行調整,刪掉條目2,並去掉條目背景色,同時爲容器加上白色背景。修改後效果和代碼如下

<!--塊容器開始-->
<div class="ub ub-ver uba b-gra uc-a1 t-bla c-wh">
<div class="ubb b-gra uinn uc-t1">
條目
1</div>
<div class="uinn uc-b1 ">
條目
3</div>
</div>
<!--
塊容器結束-->

上圖我們可以看到,我們調整了容器的背景爲白色,字體色彩爲黑色,子條目沒有背景。這時我們就已經創建了一個符合要求的容器了。接下來,我們假如編輯框控件來替換條目1和條目3
我們先通過IDE中的編輯框嚮導

插入一個編輯框到條目1位置(選擇帶標籤),替換後的條目1部分代碼如下

<div class="ubb b-gra uinn uc-t1">
<!--
文本開始
-->
<div class="ub t-bla ulab"> <div class="uinn ulim">
標籤標籤
</div>
<div class="ub-f1 c-blu uba uc-a1 b-gra us-i uinput uinn4">
<input placeholder="hello" type="text" class="uc-a1">
</div>
</div><!--
文本開始
-->
</div>

目前的效果和我們需要的效果有些偏差我們需要調整一下。首先標籤部分不需要再有一個內邊距(uinn),其次編輯框也不需要有任何的背景邊框效果,我們刪掉這些類。調整後的效果如下

代碼:

<div class="ubb b-gra uinn uc-t1">
<!--
文本開始
-->
<div class="ub t-bla ulab ub-ac"> <div class="ulim">
用戶名
</div>
<div class="ub-f1 uinput uinn4">
<input placeholder="hello" type="text" class="uc-a1">
</div>
</div><!--
文本開始
-->
</div>

上面的代碼可以看到,對於一個編輯框,我們採用了彈性盒子模型,編輯區域通過ub-f1實現了寬度彈性變化。到此,我們完成了條目1部分的替換,接着我們拷貝這個代碼替換條目3。最終效果如下

這裏用到了一個小技巧,我們看到上面的圖示裏"用戶名:""密碼:"並不一樣長,造成標籤部分寬度不同,這會引起後面的編輯框區域寬度也不同,我們在"密碼:"後面添加了一箇中文空格來保證界面的排版。這是一個簡單但有效的方法。
下面我們再增加兩個按鈕。首先在編輯區域容器下方再構建一個橫向排列容器。

這個容器用來容納我們的那兩個按鈕。

<div class="ub uba b-gra c-blu c-m1 t-wh uc-a1 ">
<div class="ubr b-gra ub-f1 uinn uc-l1">
條目
1</div>
<div class="ubr b-gra ub-f1 uinn ">
條目
2</div>
<div class="ub-f1 uinn uc-r1">
條目
3</div>
</div>
</div>

建立好的容器只有兩個按鈕,也不需要任何背景。我們對模板進行刪減。
清理後的代碼如下

<!--塊容器開始-->
<div class="ub ">
<div class="ub-f1 uinn">
條目
1</div>
<div class="ub-f1 uinn">
條目
2</div>
</div>
</div>
<!--
塊容器結束-->

接着我們需要加入兩個按鈕來替換條目1和條目3的文字,通過IDE的按鍵控件嚮導我們插入兩個按鈕,通過高級模式調整好色彩,並修改文字色。

<!--塊容器開始-->
<div class="ub ">
<div class="ub-f1 uinn">
<!--
按鈕開始
-->
<div ontouchstart="zy_touch('btn-act')" class="btn uba b-gra uinn5 c-wh c-m1 uc-a t-bla">
確定
</div>
<!--
按鈕結束
-->
</div>
<div class="ub-f1 uinn">
<!--
按鈕開始
-->
<div ontouchstart="zy_touch('btn-act')" class="btn uba b-org uinn5 c-org c-m1 uc-a t-wh">
確定
</div>
<!--
按鈕結束
-->
</div>
</div>
<!--
塊容器結束-->

到此,我們完成了基本的界面排布。我們再稍微的調整一下幾個容器的間距即可。Demo009範例是調整完後的完整代碼。我們通過一個範例來展現了AppCan UI2.0中的容器的使用方法。目前我們看到不管是一個容器、一個按鈕或一個編輯框,都是依賴於彈性盒子模型實現的佈局。

4.3 編輯框

上一節呢,我們用到了編輯框,這裏我們對編輯框的使用作一個詳細的講解。AppCan UI2.0平臺提供了多種編輯框的默認效果。

有普通單行文本框、文本區域和搜索框。同時控件與按鍵控件一樣,也支持高級模式來定義效果。上一個例子裏我們使用了普通的編輯框,這個例子我們主要介紹搜索框和文本區域。
搜索框
一般搜索框常會用在標題下面,我們對index.html頁面做一下調整,在標題欄和內容區域之間插入一個搜索框。代碼如下

<!--文本開始-->
<form id="search" οnsubmit="alert('submit')">
<div class="t-bla ub uba uc-a b-gra us-i uinput ub-rev uinn4">
<div class="res6 umw1 ub-img ">
</div>
<div class="ub-f1 uinn1">
<input placeholder="search" type="text" class="" style="background:none;">
</div>
</div>
</form>
<!--
文本結束-->

上面代碼我們可以看到搜索框被放置到一個form表單裏,這樣手機的輸入法會根據輸入框的類型動態的匹配鍵盤效果。例如在鍵盤上確認按鈕顯示"搜索"等。由於在content區域前插入了搜索框,那麼下方構建浮動窗口的代碼中,浮動窗口位置也需要進行調整爲Header高度加上搜索框高度。

zy_con("content", "index_content.html", 0, $$("header").offsetHeight+$$("search").offsetHeight);
zy_resize("content",0,$$("header").offsetHeight+
$$("search").offsetHeight);

調整後的代碼見附件Demo0010範例
目前搜索框兩邊的圓角並沒有使其顯示成半圓形,我們只需要調整一下搜索框容器的uc-a類爲uc-a2即可,uc-a2是一個更大的圓角。最終效果如下

輸入域
接下來我們在index_content.html中添加一個輸入域。通過編輯框嚮導創建一個帶標籤的輸入域。

插入代碼後效果如下。

<!--文本開始-->
<div class="ub t-bla ulab">
<div class="uinn ulim">
標籤標籤

</div>
<div class="ub-f1 uba uc-a1 b-gra us-i uinput uinn4 ub ub-ver">
<textarea placeholder="hello" name="area1" class="uc-a1 ub-f1"></textarea>
</div>
</div>
<!--
文本結束-->

這裏呢我們希望標籤和輸入域縱向排列。很簡單,我們在容器後面加入ub-ver使子元素縱向排列。

<!--文本開始-->
<div class="ub t-bla ulab ub-ver">
<div class="uinn ulim">
標籤標籤

</div>
<div class="ub-f1 uba uc-a1 b-gra us-i uinput uinn4 ub ub-ver umh6">
<textarea placeholder="hello" name="area1" class="uc-a1 ub-f1"></textarea>
</div>
</div>

編輯框的高度我們添加umh6來控制,如果需要調整別的高度,可以在ui-base.cssumh6下方參照umh6定義自己的高度類,並替換上述代碼中的umh6即可。
我們對上面的代碼進行一個分析。
首先最外側是一個容器,這個容器採用彈性盒子架構(ub),定義了默認文本色(t-bla),由於有標籤,所以我們加入了標籤類(ulab),他主要控制標籤和編輯區域的橫向間距,如果縱向排列這個類可以刪除。容器中有兩個子元素,一個是標籤一個是子容器。標籤元素使用uinn爲齊添加內邊距,使用ulim來限制其長度。子容器用於定義編輯框的效果即陰影(us-i)、高度(umh6)、邊框(b-grauba)。爲了使輸入域與邊框間留下空隙,我們爲子容器加上內邊距(uinn4)uinput定義textarea元素的效果,ub定義此子容器依然是一個彈性盒子。由於輸入域在適配中的特殊性,我們爲子容器定義ub-ver,要求妻子元素縱向排列。接着我們爲textarea指定ub-f1,使其撐滿整個容器內邊距內區域。最後的代碼看附件Demo011範例

4.4 下拉列表控件

下拉列表控件經常用於在有限的區域內實現單選效果或多選,這個控件在應用開發中非常常見。我們對select標籤進行了封裝,使其有可定製化的現實效果。打開AppCan IDE(UI2.0),我們選擇中標紅的按鈕,進入下拉列表製作嚮導。

下拉列表同之前的控件一樣,可以通過高級模式配置效果。我們建立一個帶標籤的下拉列表,並對其代碼進行講解。Demo012範例
效果:

代碼:

<!--下拉列表開始-->
<div class="ub t-bla">
<div class="uinn ulim">
標籤標籤
</div>
<div class="ub-f1 ub uba uc-a1 c-wh b-org us-i sel"> 
<div class="ub-f1 ut-s uinn ulev-1 tx-l">
下拉列表
</div> 
<div class="ubl b-org c-red c-m2 umw2 ub ub-pc uc-r2 ub-ac"> 
<div class="ub-img umw1 umh1 res3"></div> 
</div> 
<select name="sel0" selectedindex="0" id="sel0" οnchange="zy_slectmenu(this.id)"> 
<option>item1</option> 
<option>item2</option> 
<option>item3</option> 
<option>item4</option> 
</select> 
</div>
</div> 

上面代碼中,我們可以看到這個控件是由一個容器中包含的標籤部分和下拉列表部分組成。下拉列表中又分三個部分:
  文字區域-用於顯示選中的條目內容

  按鈕區域-是一個容器包含一個下箭頭的圖標。這個圖標通過彈性盒子進行居中顯示
  ■Select控件-是一個與整個下拉列表容器等高寬的透明控件,這樣用戶看到的是我們的文字區域和按鈕區域,但實際點擊時,點擊的是系統Select控件。在select控件中我們通過zy_selectmenu接口截取用戶選中的條目,修改文字區域內容
上述控件中,不管是最外面的容器還是子容器,我們都使用的是彈性盒子模型。

4.5 導航欄

在應用開發中,導航欄是組織內容的一種常見方式。它可以給用戶更直觀的選擇和良好的交互體驗。AppCan IDE UI2.0)框架對UI1.0中的導航欄控件進行了調整,使用新的彈性盒子模型重新構建了代碼,更加便於開發者進行調整定製。我們通過選擇IDE控件欄中標紅的按鈕,來構建一個導航欄。導航欄也可使用高級模式來設定背景色和漸變。我們在index.html中的footer部分構建一個導航欄。Demo013範例
效果:

代碼:

<!--iPhone導航條開始-->
<div class="ub c-bla c-m1 tab t-wh">
<input class="uhide" type="radio" name="tabSwitch" checked="true">
<div ontouchstart="zy_touch('',zy_for)" class="ub-f1 ub ub-ver tab-act"><div class="ub-f1 ub-img5 tp-info"></div><div class="uinn ulev-2 tx-c">
新聞
</div></div>
<input class="uhide" type="radio" name="tabSwitch">
<div ontouchstart="zy_touch('',zy_for)" class="ub-f1 ub ub-ver tab-act"><div class="ub-f1 ub-img5 tp-home"></div><div class="uinn ulev-2 tx-c">
新聞
</div></div>
<input class="uhide" type="radio" name="tabSwitch">
<input class="uhide" type="radio" name="tabSwitch">
<div ontouchstart="zy_touch('',zy_for)" class="ub-f1 ub ub-ver tab-act"><div class="ub-f1 ub-img5 tp-set"></div><div class="uinn ulev-2 tx-c">
新聞
</div></div>
<input class="uhide" type="radio" name="tabSwitch">
<div ontouchstart="zy_touch('',zy_for)" class="ub-f1 ub ub-ver tab-act"><div class="ub-f1 ub-img5 tp-shop"></div><div class="uinn ulev-2 tx-c">
新聞
</div></div>
<input class="uhide" type="radio" name="tabSwitch">
<div ontouchstart="zy_touch('',zy_for)" class="ub-f1 ub ub-ver tab-act"><div class="ub-f1 ub-img5 tp-talk"></div><div class="uinn ulev-2 tx-c">
新聞
</div></div>
</div>

上述代碼可以看到,整個導航欄是由一個彈性盒子容器包含5個條目組成的,如果用戶需要事先大於5個或小於5個的導航欄,只需要拷貝複製或刪除條目即可。每個條目又是由一個radiobox控件和一個縱排的彈性盒子子容器組成。在子容器中,包含圖片和文字兩個子元素。我們對這些組成部分進行一下分析。
  ■radiobox控件-此控件爲隱藏控件,並不現實(uhide),他的作用是通過和其他具有同樣name屬性的radiobox控件組合使用,來實現條目的單項選擇,配合後面子元素的CSS類屬性實現選中和未選中效果。
  子容器-用於容納每一個條目的子元素。同時負責顯示選中和未選中狀態(tab-act)。我們看一下ui-tab.csstab-act的定義。

input[type="radio"]:checked + div.tab-act
{
background-color:rgba(255,255,255,0.1) !important;
border-radius:0.3em;
border: 0px;
background-image: none;
}

  上面代碼可以很清晰的看到當一個radiobox 被選中狀態下,他相鄰的那個div中的tab-act類表示一個透明度爲0.1的圓角矩形。未選中狀態下無效果。通過這個類配合之前的單選鈕我們可以很簡單的實現條目的選中未選中狀態變化。
  圖片元素-用於顯示每一個條目得圖片(tp-info)。由於每個條目的圖片不同,需要爲每個圖片元素設定圖片資源。目前我們在ui-tab.css中預置了六組圖片資源類,用戶可以根據需求替換相應的圖片資源。每一組圖片資源分選中狀態和爲選中狀態,我們以tp-info爲例進行分析。

input[type="radio"] + div>div.tp-info{
background: url(res-apple/info.png) 50% 50% no-repeat;
}

input[type="radio"]:checked + div>div.tp-info{
background: url(res-apple/info-act.png) 50% 50% no-repeat;
}

  上述代碼中,可以看到當一個radio未選中時,與他相鄰的div中的子div元素具有的tp-info屬性對應背景圖片爲info.png。當選中時,與他相鄰的div中的子div元素具有的tp-info屬性對應背景圖片爲info-act.png。即配合radiobox我們可以簡單的實現圖片的變化。
導航欄並不一定都是這種顯示效果,我們修改一下代碼實現以下另一種效果。

這是上面是中文下方是英文的效果。附件是代碼Demo014範例。我們調整了子容器的元素,從一個圖片變爲了兩組文字框。

<div ontouchstart="zy_touch('',zy_for)" class="ub-f1 ub ub-ver tab-act"><div class="uinn3 tx-c">新聞</div><div class="uinn ulev-1 tx-c">news</div></div>

上面展示的良種效果會有些問題,我們可以看到每一個子容器都是通過ub-f1進行等分的,但在文章最開始我們介紹時提到過,如果自容器中的內容並不等長時,瀏覽器會動態的調整每個字元素的寬度即時齊都是相同的flex屬性。如果確實出現了文字不等長的情況,我們該如何調整呢?我們調整一下Demo014範例的代碼Demo015範例

<div ontouchstart="zy_touch('',zy_for)" class="ub-f1 ub ub-ver tab-act uinn3">
<div class="tx-c umh2 umar-b umar-t">
<div class="ub-con ulev-1 ut-s">
早間新聞
</div>
</div>
<div class="ulev-1 tx-c umh1">
<div class="ub-con">news</div>
</div>
</div>

相對於之前,修改後我們爲文字外添加了一個容器,通過ub-con定義此文字區域的高寬與父元素相同。而之前每一個文字區域的高度都是被文字撐開的,所以此時爲了保證文字區域的高度,我們分別爲兩個文字區域設定了umh2umh1的最小高度值。由於ub-con定義使用了position:absoluteheight:100%屬性,則其高度是父容器的邊框高+內邊距高+內容高,因此我們不能爲原來的文字區域再指定內邊距,我們爲條目容器指定了uinn3的內邊距來代替原來爲文字區域設定的uinn3,通過爲上方的文字區域指定上下外邊界來爲兩個文字區域進行分隔。通過這種寫法,我們可以在各條目文字長度不同的情況下保持寬度的一致。同樣,在頁面設計中ub-con也可以用到其它有類似問題的地方。
導航條的目的是爲了配合頁面的切換。那麼下面我們演示一下如何通過導航條快速實現頁面切換。我們目前已經有了一個index.html和一個index_content.html,那麼我們爲index.html頁面在建立一個內容頁面。複製index_content.html,改名爲msg_content.html。這個時候我們就有了兩個內容頁面。我們在script區域添加兩個函數

function loadmsgcontent(){
zy_con("content", "msg_content.html", 0, $$("header").offsetHeight);
}
function loadindexcontent(){
zy_con("content", "index_content.html", 0, $$("header").offsetHeight);
}

第一個函數用於修改名字爲content的浮動窗口加載的頁面爲msg_content.html,第二個函數用於修改content浮動窗口加載的頁面爲index_content.html。然後我們爲導航欄中第一個元素和第二個元素分別加上onclick事件,

<div ontouchstart="zy_touch('',zy_for)" οnclick="loadindexcontent()" class="ub-f1 ub ub-ver tab-act uinn3">
<div class="tx-c umh2 umar-b umar-t">
<div class="ub-con ulev-1 ut-s">
早間新聞
</div>
</div>
<div class="ulev-1 tx-c umh1">
<div class="ub-con">news</div>
</div>
</div>
<div ontouchstart="zy_touch('',zy_for)" οnclick="loadmsgcontent()" class="ub-f1 ub ub-ver tab-act uinn3">
<div class="tx-c umh2 umar-b umar-t">
<div class="ub-con ulev-1 ut-s">
新聞
</div>
</div>
<div class="ulev-1 tx-c umh1">
<div class="ub-con">news</div>
</div>
</div>

此時我們可以看到,當我們點擊第一個條目和第二個條目時,中間區域的網頁內容發生了改變。範例工程參閱附件Demo016範例

4.6 單選框和複選框

單選和複選框是應用中常見的組件,他們一般都會按組的方式實現。我們通過IDE中標紅的兩個按鈕來生成複選和單選控件。我們打帶複選框嚮導

構建一個單個複選框按鈕,並對其代碼進行分析

代碼:

<!--複選框開始-->
<input type="checkbox" name="che1" class="uhide" checked="checked" value=""> 
<div οnclick="zy_for(event)" ontouchstart="zy_touch('btn-act')" class="ub uc-a1 uba c-gra c-m2 b-gra t-bla uinn5 ">
<div class="ub-f1 ut-s tx-l" >item</div>
<div class="che-icon ub-img umw1"></div> 
</div>
<!--
複選框結束-->

述代碼可以看到一個複選框由一個隱藏(uhide)checkbox和一個複選框容器組成。複選框容器包含一個文字區域和一個選中狀態圖標。當用戶點擊這個複選框容器時觸發onclick函數,會調用zy_for函數,此函數會對這個DIV元素之前的Input標籤的checked屬性做取反操作,即如果checkedtrue則變爲false,爲false則變爲true。與之前select和導航欄控件機制一樣,我們通過input和後面元素的CLASS類組合通過input的狀態變化達到更換選中狀態圖標的效果。我們可以看一下che-icon這個類的定義。

input[type=checkbox]+div>div.che-icon {
background-color: transparent;
background-image: url(images/icons-18-white_39.png);
}
input[type=checkbox]:checked+div>div.che-icon {
background-color: transparent;
background-image: url(images/icons-18-white_37.png);
}

上述代碼種,當input被選中時,其相鄰的div中的子Div元素的che-icon屬性會設定圖片爲icons-18-white_37.png。如果未選中則設定爲icons-18-white_39.png。通過這裏我們可以看到,我們在控件中廣泛採用了input和類進行組合的方式非常簡單的實現各種效果。
複選框還有一種變形,我們看看如下範例Demo017範例,通過嚮導選擇

index_contet.html中添加一個水平分組複選框。效果如下

代碼:

<!--複選框開始-->
<div class="ub uc-a1 t-bla c-gra c-m2 uba b-gra tx-c"> 
<input type="checkbox" name="che1" class="uhide" value=""> 
<div οnclick="zy_for(event)" class="uinn5 ubr b-gra uc-l1 ub-f1 che">item</div> 
<input type="checkbox" name="che2" class="uhide" value=""> 
<div οnclick="zy_for(event)" class="uinn5 ubr b-gra ub-f1 che">item</div> 
<input type="checkbox" name="che3" class="uhide" value=""> 
<div οnclick="zy_for(event)" class="uinn5 uc-r1 ub-f1 che">item</div>
</div>
<!--
複選框結束-->

水平復選框分組其實就是一個容器包含了三個子元素,每個子元素配合一個input標籤來控制其效果(che)。我們看一下che類的代碼

input[type=checkbox]:checked+div.che {
box-shadow:inset 0 1px 2px rgba(0,0,0,0.6);
}

上述代碼表示當input被選中時,爲元素添加一個內陰影。
對於縱向排列的複選框分組就不作介紹了,大家可以自己通過模板建立一個,研究一下代碼。它其實就是一個容器裏放了多個單條複選框而已。
單選框和複選框基本代碼和設計都是一致的只是單選框的隱藏input標籤類型爲radio而已。大家可以研究一下ui-input.css中的類定義

4.7 列表控件

有人說80%的應用界面都是列表形式的,沒統計過但是從大概的感覺上可以認爲沒有什麼偏差。AppCan IDE UI(2.0)中,提供了新構建的列表模板。我們通過IDE中的列表嚮導進行構建Demo018範例

這次我們構建一個帶圖標的列表。
效果:

代碼:

<!--列表開始-->
<div class="uba b-gra c-wh us uc-a ">
<div ontouchstart="zy_touch('btn-act')" class="uc-t ubb c-m2 ub b-gra t-bla ub-ac lis">
<div class="lis-icon ub-img im"></div>
<div class="ub-f1 ut-s">
設置
</div>
<div class="tx-r t-blu ulev-1">Old Phone</div>
<div class="res8 lis-sw ub-img"></div>
</div>
<div ontouchstart="zy_touch('btn-act')" class=" ub ubb b-gra c-m2 t-bla ub-ac lis">
<div class="lis-icon ub-img im"></div>
<div class="ub-f1 ut-s">
設置
</div>
<div class="tx-r t-blu ulev-1">Old Phone</div>
<div class="res8 lis-sw ub-img"></div>
</div>
<div ontouchstart="zy_touch('btn-act')" class="uc-b c-m2 ub t-bla ub-ac lis">
<div class="lis-icon ub-img im"></div>
<div class="ub-f1 ut-s">
設置
</div>
<div class="tx-r t-blu ulev-1">Old Phone</div>
<div class="res8 lis-sw ub-img"></div>
</div>
</div>
<!--
列表結束-->

這是一個三個條目的列表,很明顯,這個列表與其他控件基本組成元素都是一致的,也是一個容器、子容器加一些元素構造而成。我們主要對一個條目進行講解。

<div ontouchstart="zy_touch('btn-act')" class="uc-t ubb c-m2 ub b-gra t-bla ub-ac lis">
<div class="lis-icon ub-img im"></div>
<div class="ub-f1 ut-s">
設置
</div>
<div class="tx-r t-blu ulev-1">Old Phone</div>
<div class="res8 lis-sw ub-img"></div>
</div>

這是列表的第一個條目,我們一行一行進行解析。

<div ontouchstart="zy_touch('btn-act')" class="uc-t ubb c-m2 ub b-gra t-bla ub-ac lis">

這是一個容器,由於是第一行,所以他的圓角要和外面容器的圓角保持匹配,因此我們爲其設定圓角(uc-t),這個容器和下一行需要一條分割線,我們設定這個子容器右下邊界(ubb),邊界色彩爲(b-gra),這個條目有一點簡便效果,我們採用的是(c-m2)由於其位於容器內,這個遮蓋層會和父容器背景色進行組合。這個子容器包含多個元素,這些元素也是以彈性盒子模型進行排版(ub),文字色彩定義爲黑色(t-bla),由於容器中的子元素高低不定,因此我們要求其子元素中線對其(ub-ac)。最後是設定列表條目的默認效果(lis 建立了內邊距)

<div class="lis-icon ub-img im"></div>

這是容器中的第一個元素,它是一個小圖片,我們設定了這個圖片的高寬(lis-icon),同時設定了這個圖片是(im),圖片的展示參數通過(ub-img)來設定。 備註:
默認工程中的ui-img.css定義了我們範例中的範例資源圖片,而ui-res.css是我們控件需要的資源圖片。

<div class="ub-f1 ut-s">設置</div>

這一行設定了一個彈性區域,他會撐滿真個容器的空閒區域(ub-f1),當文字長度超過可容納區域後,進行縮略(ut-s)

<div class="tx-r t-blu ulev-1">Old Phone</div>

這一行定義了一個文字去,這個文字區的大小會根據文字長度進行調整。我們通過ulev-1對此地的文字進行縮小顯示。並通過t-blu設定其顏色爲蘭色。

<div class="res8 lis-sw ub-img"></div>

最後這個元素是一個小箭頭圖標。lis-sw定義了他的大小,res8指定了所用的資源,ub-img定義了圖片的展示方式。
通過這部分解析我們看到一個列表其實也是由最基本的容器和元素組合而成。通過彈性盒子模型,真個列表的排佈會非常簡潔明瞭。

4.8 開關按鈕

UI2.0框架中,我們對開關按鈕進行了重新實現,配合上一個範例,我們在第一個條目中插入開關按鈕來體驗一下他的效果。Demo019範例

代碼:

<div ontouchstart="zy_touch('btn-act')" class="uc-t ubb c-m2 ub b-gra t-bla ub-ac lis">
<div class="lis-icon ub-img im"></div>
<div class="ub-f1 ut-s">
設置
</div>
<!--
開關按鈕開始
-->
<input class="uhide" type="checkbox" checked="true" >
<div class="uba b-gra swi swi-bg uc-a1" οnclick="zy_for(event)"></div>
<!--
開關按鈕結束
-->
</div>

上面代碼中,我們把前一個範例的第一個條目後面的兩個元素刪除,替換了一個開關按鈕。開關按鈕的動畫變換也是依賴於input的變化進行控制。其中swi定義了這個控件的變形動畫效果,swi-bg定義了這個開關按鈕的背景swiinput進行配合定義了不同狀態下的效果。

input[type=checkbox]:checked + div.swi{
background-position:-0.1em;
}
input[type=checkbox] + div.swi
{
background-position:-4.01em
}

input標籤被選中時,swi的背景位置是-0.3em。當未被選中時,背景位置爲-4.01em。通過背景圖片位置的變化完成選中狀態的變化。
通過上面的講解,我們展示了UI2.0的框架設計思想。並通過對我們預置組件代碼的分析,使大家對如何使用UI2.0框架調整界面有了一個基本的認識。我們總結一下我們公司開發人員的UI設計規則
1.
製作前先考慮好如何組織頁面,需要如何佈局,在什麼地方需要幾個容器來進行排版。然後構建架子,使用默認效果類進行排版定位和美化
2.
如果需要使用顏色,請在ui-color.css中根據文本、背景、遮蓋、邊框等分別擴展自己的類定義
3.
如果需要調整圓角、邊距等附加屬性請在ui-base.css中進行添加。
4.
如果需要資源,請在ui-res.css中進行擴展
5.
如果需要佈局,請在ui-box.css中進行調整
6.
所有調整要遵循默認的命名規則。
遵守這些規則可以使你的代碼更容易被其他人閱讀,代碼複用和調整將會更加簡單

 

1UI2.0UI1.0的對比

2012年初,我們發佈了AppCan移動應用開發平臺,在這個版本中,我們內置了基於JQMobile方案的CSS UI框架。這個框架可以幫助開發者遵循一套規則下,快速的開發應用。這套方案中主要採用了組合的概念。例如對一個按鈕的描述,可以通過多個CSS類來組合進行定義,也可以通過視頻瞭解更多。
這樣通過不同的組合可以生成多變的效果。在實際商用應用開發過程中,它起到了幫助我們加快開發進度的作用。但是在開發過程中,我們還是遇到了一些問題,JQMobile CSS框架在這些問題上,表現得比較乏力:
1
1 自動填充寬度


上圖中同樣一個編輯框加上一個刷新按鈕的組合。在不同分辨率下,如果希望,刷新按鈕保持一個基本寬度,編輯框自動填充剩餘區域,在不使用JS的情況下是很難做到的,如果使用百分比控制刷新鈕的寬度,那麼在低分辨率和高分辨率之間將會有非常大的偏差。
1
2 類名稱過長
JQMobile
方案中,爲了幫助開發者能夠更直觀的瞭解代碼,每一個功能類的名稱都比較長。例如ui-page ui-mobile-viewport等。這造成了網頁代碼大小變大,降低了解析速度。
1
3 類功能拆分度低
JQMobile方案中,很多類定義,代碼重複較多,例如預製的多種色彩方案。同時由於拆分度低,經常需要重複定義類來覆蓋其他類中的屬性。
1
4 控件組合複雜
JQMobile
方案中,控件的實現代碼量很大,一個按鈕需要多個div span嵌套配合多個類才能實現。這造成開發中,界面代碼量增大,不好控制界面。

我們綜合各個項目中的開發經驗,整理彙總了AppCan UI2.0架構,它繼承了UI1.0的優點,並很好地解決了UI1.0的問題,可以使開發能夠更加的簡單。UI2.0框架圖如下:

上圖中,我們可以看到AppCan UI2.0框架在基礎的屏幕適配(RESOLUTION ADAPTER CLASS)基礎上,對元素基本屬性進行了拆分。通過如下步驟來設定一個元素。
   定位-對元素進行佈局,確定元素的現實位置大小等[LAYOUT CLASS]
   描邊-對元素基礎屬性進行設定,例如邊框圓角等
[BASE CLASS]
   添色-對元素的邊框、文字和背景進行設定
[COLOR CLASS]
   插圖-如果元素中需要圖片,從資源中引入圖片類
[RES CLASS]

基於基礎元素之上,爲了方便開發者,我們重新定義了控件,包含BUTTONLISTFOLDINPUTTABRADIOCHECKSWITCH。這些控件可以認爲是UI2.0框架的具體事例。通過UI2.0完成的控件,代碼大小和複雜度,都有明顯的降低,如下例:


UI1.0
框架實現的按鍵

<div class="ui-btn ui-corner-all ui-shadow ui-btn-b"> 
  
<span class="ui-btn-inner ui-corner-all">
  <span class="ui-btn-text ">確定
</span>
</span>
</div>


UI2.0
框架實現的按鍵

<div class="btn btn-act ubb uc-t1 b-bla uinn c-blu2 c-m4 ">確定 </div>

從上述代碼中可以看到,同樣功能和效果的控件可以減少三分之二的代碼,嵌套減少到一層,代碼複雜度極大降低。
接着我們詳細介紹如何使用UI2.0框架。

2UI2.0框架的設計來源——彈性盒子模型

彈性盒子模型是CSS3.0推出的一種佈局機制。這種機制與常見的流式佈局有很大區別。簡單的理解爲,流式佈局是通過內容決定父容器大小,彈性盒子模型是,在指定大小的父容器裏來爲子元素分配空間,簡單的流式佈局例子。
效果:

代碼:

<div style="display:inline;border:1px solid blue">
  
<div style="display:inline;background:#E00">aaaa </div>
  
<div style="display:inline;background:#0E0">bbbb </div>
</div>

上述代碼中是一個簡單的流式佈局範例,第1行的div的寬度,是由第2和第3行的div寬度相加來決定的。即如果第2行或第3行的div寬度變化,第1行的寬度也會隨之變化。我們調整一下代碼,使用彈性盒子模型來佈局。
效果:

代碼:

<div style="display:-webkit-box;width:200px;border:1px solid blue">
  
<div style="-webkit-box-flex:1;background:#E00">aaaa </div>
  
<div style="background:#0E0">bbbb </div>
</div>

上述代碼中,指定第1行的div使用BOX方式佈局子元素。並指定這個div200px。第3行的div的寬度由內容撐開,可以認爲是一個指定寬度的div,通過模擬器可以看到寬32px。第2行指定這個div爲彈性,佔用1份空間,就代表這個div的寬度是總寬度200px-32px=168px。如果我們改動第1行的div寬度爲320px,那麼第2div的寬度就是 320px-32px=288px。這個機制對於適配各種分辨率的屏幕無疑是一把利器。
我們再調整一下代碼。
效果:

代碼:

<div style="display:-webkit-box;width:200px;border:1px solid blue">
  
<div style="-webkit-box-flex:1;background:#E00">aaaa </div>
  
<div style="-webkit-box-flex:2;background:#0EE">bbbb </div>
  
<div style="background:#0E0">cccc </div>
</div>

我們加入了一個佔用2份空間的div。這個時候這兩個彈性DIV到底如何分配空間呢?按照規則來說,第2行應該佔用168px/3=56px,第3行佔用112px,但實際上寬度並不是如此,通過模擬器可以看到,第34行佔用66px,第35行佔用102px。這是由於當彈性DIV中有內容時,引擎會自動進行調整。那麼如何在有內容的情況下還能夠保持12的比率呢?我們再調整一下代碼。
效果:

代碼:

<div style="display:-webkit-box;width:200px;border:1px solid blue">
<div style="-webkit-box-flex:1;background:#E00;position:relative">
 
<div style="position:absolute;width:100%;height:100%;">aaaa </div>
</div>
<div style="-webkit-box-flex:2;background:#0EE;position:relative">
<div style="position:absolute;width:100%;height:100%;">bbbb </div>
</div>
<div style="background:#0E0">cccc </div>
</div>

這次修改中,我們把內容"aaaa"通過一個使用絕對定位的div進行包含,這時通過模擬器去看會發現,兩個彈性div按照1:2的比率自動分配了空間。上面我們使用彈性盒子佈局時元素都是橫向排序的,那麼怎麼才能讓元素縱向排布呢。我們接着調整一下代碼。
效果:

代碼:

<div style="display:-webkit-box;height:200px;border:1px solid blue;-webkit-box-orient:vertical;">
<div style="-webkit-box-flex:1;background:#E00;position:relative">
 
<div style="position:absolute;width:100%;height:100%;">aaaa </div>
</div>
<div style="-webkit-box-flex:2;background:#0EE;position:relative">
<div style="position:absolute;width:100%;height:100%;">bbbb </div>
</div>
<div style="background:#0E0">cccc </div>
</div>

上述代碼中,我們在第1行的div中指定了高度爲200px,使用-webkit-box-orient:vertical來控制子元素爲縱向排列。
彈性盒子模型還提供了其他幾個強大的屬性。
 -webkit-box-direction:reverse;
通過在父DIV中設定這個屬性可以讓子元素反向排列。如下圖:

使用前子元素按照1 2 3 的順序進行排列顯示,當在父DIV中使用此屬性時,自動把子元素倒序排列。這個時候,我們並沒有真的重新按照3 2 1順序排布子元素。
 -webkit-box-align:center;
通過在父元素中設定這個屬性,當子元素橫向排布時,可以使子元素間實現上邊界對齊、中線對齊和下邊界對齊的效果

如果是縱向排列時,那麼可以實現子元素左邊界對齊、中線對齊和右邊界對齊。

 -webkit-box-pack:center;
通過在父元素中設定這個屬性,當子元素橫向排布時,可以使子元素間左邊界對齊、中線對齊和右邊界對齊

如果是縱向排列時,那麼可以實現子元素間上邊界對齊、中線對齊和下邊界對齊的效果。

如果父元素中只包含一個子元素,混合使用-webkit-box-align -webkit-box-pack可以使子元素實現居左上、居中上、局右上等9個方位的定位。
彈性BOX架構可以同時兼容流式佈局,即當所有子元素都沒有設定彈性份數時,父元素可以被子元素自動撐開。如下代碼
效果:

代碼:

<div style="display:-webkit-box;border:1px solid blue;-webkit-box-orient:vertical;">
  
<div>aaaa </div>
  
<div>bbbb </div>
  
<div>cccc </div>
</div>

在上述代碼中所有子元素都未使用box-flex定義彈動屬性,容器div也未設定高度,此時,容器div的高度爲三個子元素的高度和,並且隨着子元素的高度變化而變化。
AppCan UI2.0架構中,我們把上面遇到的情況進行了CSS類封裝
● ub
元素採用彈性BOX佈局
● ub-rev
子元素反序排列
● ub-con
在子元素中加入一個容器,用於避免內容引起子元素大小變化。
  對應CSS代碼爲position:absolute;width:100%;height:100%;
● ub-ac
ub-ae 子元素垂直居中對齊和尾對齊

● ub-pc
ub-peub-pj 子元素水平居中對齊、尾對齊和兩端對齊
● ub-ver
子元素縱向排列
● ub-f1 ub-f2 ub-f3 ub-f4
子元素佔用區域份數
通過上述類,我們可以完成各種各樣的排版佈局,極大地降低學習難度和元素排版複雜度,使代碼更加簡練。

32UI2.0框架開發指南

3.1 基石 (UI的分辨率適配)

  每一個手機應用,如果需要在衆多的移動終端上保持一致的效果,UI適配是工作的重中之重。UI2.0框架與UI1.0框架在屏幕適配機制這一部分依然保持一致。設計原理是爲不同分辨率的系統,選取最貼近於人直觀感受舒適度的一個字體大小作爲參考量。例如在320x480分辨率的手機上,採用16px大小字體作爲參考量。在480x800分辨率的終端上,採用24px大小字體作爲參考量。一切元素的大小都是以參考量的相對比值來定義。在CSS裏面對應的是em。那麼在320x480分辨率下 1em=16px,在480x800分辨率下1em=24px。 
  通過這種方式,我們可以保證,同樣代碼的界面,在不同分辨率下都能夠保持最貼近用戶的交互效果。
  在UI1.0中,我們在HTML文件中引用ui-media.css,即可處理當前常見分辨率的適配。但是由於各手機平臺不同,和各種新分辨率手機的問世,都對適配工作提出了更高的要求。
  UI2.0中,我們在中間件中爲不同屏幕密度(單位尺寸中可顯示的點數),默認定義好了字體,開發者不再需要在代碼中引入ui-media.css文件,即使有新的分辨率手機問世,也會自動適配。目前參照Andorid屏幕密度劃分爲低密度、普通密度、高密度、超高密度,分別定義字體爲14px 16px 24px 32px

3.2 骨架(元素佈局與定位)

在選定好的基石之上,我們需要爲我們的目標界面,搭建骨架。骨架從構建上可以分爲主幹和旁支。
主幹
主幹可以認爲是整個頁面的整體框架佈局

上圖是截取與ZAKER(原生開發)、正益無線(HTML5開發)ZAKER微博界面(原生開發)HTML5中國(HTML5開發)。參考上述界面我們看到大部分應用的頁面都遵循標題+內容+底部欄的佈局方式。AppCan UI2.0提供了簡單的佈局架構模板來適配這種佈局。Demo007範例下載

模板代碼中我們可以看到默認存在index.htmlindex_content.html兩個文件。我們通過對這兩個文件的分析來講解AppCan UI2.0推薦的應用開發模式。index.html文件分爲三部分HEADBODYSCRIPT
HEAD
部分:

<head>
<title></title>6
<meta charset="utf-8">
<meta name="viewport" content="target-densitydpi=device-dpi, width=device-width, initial-scale=1, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"<
<link rel="stylesheet" href="css/ui-base.css">
<link rel="stylesheet" href="css/ui-box.css">
<link rel="stylesheet" href="css/ui-color.css">
<link rel="stylesheet" href="css/ui-res.css">
<script src="js/zy_control.js">
</script<
<script src="js/zy_click.js">
</script>
</head>

這一部分定義了網頁引用的CSSJS文件。上面代碼中ui-base.css代表基礎類文件,ui-box.css是彈性盒子封裝類文件,ui-color是色彩基礎類文件。zy_control.js是默認控件和網頁需要的一些默認功能支持類。zy_click.jsClick事件模擬類,用於替代默認的onclick事件(手機中onclick響應較慢使應用體驗性差)
BODY
部分

<body class="um-vp c-wh" ontouchstart>
 
<div id="page_0" class="up ub ub-ver" tabindex="0">
<!--header
開始
-->
 
<div id="header" class="uh c-org c-m1 t-wh">
 
<h1 class="ut ulev0 ut-s tx-c" tabindex="0">AppCan</h1>
</div>
<!--header
結束--> <!--content開始
-->
 
<div id="content" class="ub-f1 tx-l t-bla ub-img6 res10">
</div>
<!--content
結束--> <!--footer開始
-->
 
<div id="footer" class="uf c-m2 c-bla t-wh">
 
<h1 class="ut ulev-2 tx-c" tabindex="0">(c) Copyright 3G2WIN and others 2011.
<br>
All rights reserved. </h1>
</div>
<!--footer
結束
-->
</div>
</body>

Body部分定義了一個頁面page_0,這個頁面的高度爲屏幕高度(up),使用彈性盒子佈局(ub),它的子元素縱向排列(ub-ver)。這個頁面中包含headercontentfooter三個區域。
header
footer部分是一個DIV,是一個定高的區域(通過內容撐開)content是一個彈性區域,它會佔滿page_0中除了headerfooter外的區域。如果headerfooter的高度變化,content的高度也會隨之變化。但是這種佈局當內容區域有內容時會引起整個content的高度撐高,由於大部分移動終端都不支持DIV的內部區域滾動,這回造成整個頁面能夠被拖動,這是與我們要求不符的。我們通過SCRIPT區域的代碼來處理這個問題。
SCRIPT
部分:

<script>
zy_init();
window.uexOnload = function(type){
if (!type) {
zy_con("content", "index_content.html", 0, $$("header").offsetHeight);
}
window.onorientatiοnchange=window.οnresize=function()
{
zy_resize("content",0,$$("header").offsetHeight);
}
}
</script>

上述代碼中zy_init函數用於在模擬器中實現字體的自動適配。在手機中無作用。
window.uexOnload
事件用於在AppCan中間件擴展對象加載完成後調用。在這個函數裏,我們調用了封裝在zy_control.js裏的zy_con函數創建了一個浮動VIEW。這個Viewcontent的區域保持同樣的大小,位置也與content區域的位置保持相同。這個View顯示的內容來自於index_content.html頁面。也就是說,我們的index.html頁面中content區域其實並不包含內容,它只起到一個定位的作用,爲浮動View提供定位支持。
window.onorientatiοnchange=window.onresize
這行代碼爲iOSAndorid平臺的屏幕旋轉事件指定了回調函數,當發生屏幕旋轉時,會調用這個函數,此時我們調用封裝的zy_resize接口參照content區域的新的高寬位置重新定位了浮動窗口。
更方便的是,開發者可以爲content區域開發不同的content頁面,可以根據的操作隨時使用zy_con接口變更content區域的頁面內容來實現不同的功能。例如可以配合下方的導航條控實現功能切換。

AppCan UI2.0框架推薦這種方式來編寫頁面,相對於UI1.0框架來說,處理邏輯更加簡單,適配更加方便,並且在一個窗口中,並不是只允許包含一個浮動窗口,我們可以創建多個浮動窗口來完成不同的功能,輕鬆的實現功能的拆分,減少在一個頁面中實現衆多功能引起的邏輯問題。同時這種方式可以輕鬆的實現固定的背景圖片。上述代碼中,我們看到我們爲content區域指定了一張背景圖,而我們在index_content.html沒有指定背景色,這樣顯示index_content.html網頁時會顯示出蓋在在下方的content區域。由於浮動窗口是獨立的窗口,因此它的頁面滾動並不會影響下方content區域。當然這種佈局我們使用iscrollJS包也可以很方便的實現,但是在很多Android手機上,由於性能原因體驗相對於原生應用還是會有很大差距。
AppCan UI2.0
框架支持浮動窗口的彈動效果,開發者可以很方便的實現彈動效果,在index_content.html中我們已經默認提供了範例代碼。接着我們看一下實際的內容區域網頁index_content.html。這個頁面與index.html一樣同樣分爲三個部分HEADBODYSCRIPTHEAD部分與index.htmlHEAD部分一樣沒什麼區別。BODY部分開發者可以根據需求添加列表、表單、地圖等功能實現。SCRIPT部分的代碼我們看一下:

<script>
zy_init();
window.uexOnload=function(type)
{
if(!type){
uexWindow.setBounce("1");
uexWindow.showBounceView("0","#FFF","0");
uexWindow.showBounceView("1","#FFF","0");
}
}
</script>

上述代碼中zy_init()用於在模擬器狀態下實現字體自適配,手機上無作用。uexOnload事件定義了浮動窗口AppCan擴展加載後的回調函數。當加載成功後,我們會調用AppCan彈動接口爲浮動窗口添加彈動效果,並設定彈動背景色。大家可以使用範例應用來體驗一下。
旁支
在完成頁面後,我們需要對頁面中的元素進行佈局。使用彈性盒子,將使這個佈局工作的難度降低很多。我們定一個目標,如下圖

我們可以對他進行如下區域劃分。

 左側定寬圖片區域
  圖片子區域
右側文字區域
  文字正文區域
  文章屬性區域
我們在index_content.html種進行佈局,代碼如下
效果:

代碼:

<div οnmοusedοwn="zy_touch('btn-act')" class="ubb ub b-gra t-bla lis">
<div class="lis-th ub-img im">
<div class="ub-f1 ub ub-ver">
<div class="ulev1"><
標題名
>
<div class="ulev-1 umh4 t-gra">
文本說明
</div>
<div class="ub ub-ac t-gra ulev-2">
<div class="umh2 umw2 ub-img " style="background-image:url(css/img/icon1.png);">
<div class="ub-f1">
收藏數
</div>
<div class="umh2 umw2 ub-img " style="background-image:url(css/img/icon2.png);">
<div class="ub-f1">
評論數
</div>
</div>
</div>
</div>

上述代碼中,我們首先定義了一個容器,通過class="ubb ub b-gra t-bla lis"設定容器的下邊框爲灰色(ubb b-gra),文字色爲黑色(t-bla),容器採用彈性盒子佈局(ub),容器是一個list條目(lis)然後我們在容器中構建了一個縮略圖元素class="lis-th ub-img im",指定了縮略圖大小(lis-th),定義了縮略圖的顯示方式(ub-img)和縮略圖圖片資源(im)。由於圖片區域定寬,文字區域是彈性的,因此我們爲文字區域構建了容器ub-f1 ub ub-ver,容器寬度爲彈性(ub-f1),容器也採用彈性盒子佈局(ub),容器中的元素採用縱向佈局(ub-ver)。我們分別在容器中加入標題、文本說明。收藏評論欄我們認爲又是一個容器,這個容器中的字元素採用橫向佈局。我們在其中加入兩個小圖片和兩段文字收藏數評論數。到此我們就完成了這個界面的佈局。
這個例子只是一個簡單的佈局應用範例,通過這個例子來展示,AppCan UI2.0在佈局頁面時的簡便性。

3.3 皮膚-元素的美化

當我們爲一個元素設定完佈局和位置後,接着就是要對這個元素進行美化。使人舒服的外表是吸引使用者的重要因素。AppCan UI2.0框架中對一個元素的效果屬性分化爲幾類,通過這些不同類別屬性的組合來完成對元素UI的設定。

大小位置形狀控制
 圓角類別: uc-{類型}[類型] [類別]
 
uc-tl, uc-tr, uc-bl, uc-br , uc-t, uc-b, uc-r , uc-l, uc-a, uc-n, uc-tl1, uc-tr1, uc-bl1, uc-br1, uc-t1, uc-b1, uc-r1, uc-l1, uc-a1, uc-a2, uc-a3
 陰影類別: us [類別]us-i [類別
]
 
us,us1,us-i
 比例類別:ulev[類別](由於元素的控制主要通過em來進行相對控制,ulev可以對默認比率進行放大縮小
)
 
ulev2,ulev1,ulev0,ulev-1,ulev-2 
 浮動類別: ufl
ufr
 限寬類別
: ulim
 單行類別
: uinl
 邊距類別: uinn[類別
]
 
uinn,uinn1,uinn2,uinn3,uinn4 
 最小高寬類別: um{wh}[類別
]
 
umh1,umh2,umh3,umh4,umh5,umh6,umw1,umw2,umw3 
 文字對齊類別:tx-{類型
}
 
tx-l,tx-r,tx-c 
 文字縮略類別
:ut-s
 邊框類別:ub{類型}[類別
]
 
ubt,ubb,ubr,ubl,uba,uba1,uba2
 隱藏類別
:uhide
 間隔類別:umar-{類型
}
 
umar-b
色彩控制

UI2.0
框架對元素的色彩劃分爲邊框色、文字色、背景底色和背景遮蓋層
 背景遮蓋類別: c-m{類別}
 
c-m1,c-m2,c-m3,c-m4,c-m5,c-m6,c-m7
 背景底色類別: c-{色彩}[類別
]
 
c-blu,c-blu1, c-blu2, c-blu3, c-blu4,c-wh, c-bla,c-gra,c-gra1,c-gra2,c-gre,c-red,c-yel
 文字色類別:t-{色彩}[類別
]
 
t-bla,t-wh,t-gra,t-blu
 邊框色類別:b-{色彩}[類別
]
 
b-bla,b-wh,b-gra,b-gra1,b-blu
資源控制

UI2.0
框架一些常用圖片資源進行了定義。例如搜索圖標等。
 資源類別:res{類別}
 
res1,res2,res3,res4,res5,res6,res7,res8,res9,res10
AppCan UI2.0
框架對一個元素的基礎屬性進行了拆分整理,通過不同的組合來定製元素效果,同時這個方案也是一種規則,開發者可以根據具體的實際情況在對應的類別中擴展自己需要的特效。遵循這個規則可以提高代碼的可重複利用率和維護管理效率,避免團隊開發中由於各種自定義類別混亂定義引起的UI適配和維護問題。同時使用UI2.0框架構建的控件,代碼量將會極大地減少。下面一節我們將對各種常用在應用中的控件的實現來使大家瞭解UI2.0UI實現上的巨大優勢。

4UI2.0中的控件

4.1 按鈕

上面圖片展示了一些按鈕的效果,我們通過代碼看一下IDE是如何使用基礎類來定義這些按鈕的。我們選擇index_content.html,在其Body區域添加一個按鈕。在AppCan IDE(UI2.0)中,我們選擇中標紅的按鈕,進入按鈕製作嚮導。

在上面這個界面中,我們可以選擇建立普通按鈕、帶圖標按鈕和特殊定義按鈕例如iOS效果按鈕等。一般情況下按鈕會佔滿整個容器,選擇內聯可以使按鈕和其他控件在不超出容器寬度的情況下保持在同一行。如果按鈕在標題或頁腳中,可以選擇居於左側或右側。高級模式可以對按鈕的顯示效果進行配置。

上面的界面中,我們可以配置按鈕的圓角、邊框、邊框色、背景色和背景遮蓋漸變色。這些效果不光是對按鈕起效,對於其他控件也是同樣的定義。這裏定義的效果只是我們預置的效果,開發者如果需要定義自己的色彩時,只需要在ui-color.css中添加自己的類定義後,對代碼中的默認顏色類進行替換即可。我們添加一個深藍色的按鈕。
效果:

代碼:

<!--按鈕開始-->
<div ontouchstart="zy_touch('btn-act')" class="btn uba1 b-bla uinn5 c-blu c-m1 uc-a t-wh">
確定
</div>
<!--
按鈕結束-->

首先使用btn來定義這個DIV是一個按鈕(我們爲不同控件類型定義了一個標識類,用於定義一些此類控件通用的屬性)。然後使用uinn5在文字外定義了一個內邊距,這樣按鈕的高度就是內邊距+文字高度。使用uc-a定義按鈕四個圓角都爲0.6em。接着我們使用c-blu指定背景色爲藍色。在通過c-m1在藍色上加了一層漸變遮蓋層。使用t-wh定義文字爲白色。
最後我們通過uba1指定邊框所有邊都爲2px寬,並通過b-bla設定邊框色爲黑色。到此就完成了一個按鈕在不點擊狀態下的效果。相對於之前UI1.0中一個普通按鈕需要一個DIV和兩個SPAN的嵌套要簡化了2/3的代碼,層次也減低到一層。現在我們爲這按鈕加上點擊效果。按照標準CSS3來說,只需要使用僞類:active來設定一個類即可完成鼠標按下彈起的效果變換,但很遺憾,在Andorid平臺,這個效果大部分手機支持的都有問題。對於iOS平臺這個屬性是支持的,但是如果想使這個僞類有效,則必須在代碼中加入ontouchstart,才能夠激活這個僞類。爲了解決這個跨平臺問題,我們提供了zy_touch接口,通過這個接口,它可以完成點擊效果的處理。
這段代碼中,我們加入了ontouchstart="zy_touch('btn-act')"zy_touch是封裝在zy_control.js中的擴展函數,btn-act是我們預定義的一個通用控件點擊凹陷效果類。通過這個函數,我們構建了一個點擊監聽類zyClick(如果使用zy_touch還需要引用zy_click.js),他會監聽觸摸屏事件,來控制爲按鍵增加和去除點擊效果,同時可以判斷是否爲點擊操作,如果判定成功,會直接調用參數中的回調函數來達到onclick事件的效果,可以解決手機瀏覽器中onclick不靈敏的問題。同時zy_touch還支持直接調用HTML代碼中的onclick屬性實現點擊效果。我們調整代碼
代碼:

<!--按鈕開始-->
<div ontouchstart="zy_touch('btn-act')" οnclick="alert(1)" class="btn uba1 b-bla uinn5 c-blu c-m1 uc-a t-wh">
確定
</div>
<!--
按鈕結束-->

上述代碼中我們可以看到,我們註冊了onclick函數,zy_touch會直接截獲onclick事件,代替系統調用onclick代碼,而不會調用兩次onclick。這種寫法更貼近於開發者正常應用的寫法。另外,由於目前模擬器中還不支持ontouchstart事件,因此上述代碼ontouchstart不會被執行,模擬器重看不到點擊效果,但onclick函數還是會被調用。
如果希望在模擬器上看到效果,可以替換ontouchstartonmousedown。雖然手機中也支持onmousedown事件但是他的效果和時序和touch事件有差別,因此我們在手機中運行的時候還是要替換回ontouchstart
上面的按鈕是使用DIV實現的,而DIV默認是一個塊。因此會佔滿整個寬度。如果需要使按鈕與其他控件在同行顯示,我們需要爲齊添加uinl類。
效果:

代碼:

<!--按鈕開始-->
<div ontouchstart="zy_touch('btn-act')" οnclick="alert(1)" class="btn uba1 b-bla uinn5 c-blu c-m1 uc-a t-wh uinl">
確定
</div>
<!--
按鈕結束-->

我們可以看到按鈕的寬度已經不是整行顯示而是根據按鈕中的文字寬度、邊框寬度、內邊距寬度來展現。需要注意的是,uinl會和ub有效果衝突,在彈性盒子模型中,子元素需要處於塊模式(display:block)。剛纔介紹的是一個最簡單的按鈕,好我們現在爲按鈕增加一個圖標。在IDE中選擇按鈕嚮導,在按鈕類型中,選擇帶圖標按鈕。同樣配置爲深藍色。
效果如下:

代碼:

<!--按鈕開始-->
<div ontouchstart="zy_touch('btn-act')"class="btn uba1 b-bla c-blu c-m1 uc-a ub t-wh uinn5 ub-ac">
<div class="ub-f1 ut-s">
確定
</div>
<div class="umh1 umw1 ub-img res1 c-bla uc-a"></div>
</div>
<!--
按鈕結束-->

無圖標的按鈕中,我們直接在DIV中加入了文字。這次因爲有圖標我們認爲按鈕中分左右兩個區域,左側文字區域自動適配寬度,右側圖標區域寬度固定。文字和圖標中線對齊。首先我們定義按鈕的外部效果class="btn uba1 b-bla c-blu c-m1 uc-a ub t-wh uinn5 ub-ac",這個與之前的按鈕無區別,唯一添加的是 ubub-ac分別代表子元素採用彈性盒子佈局,子元素中線對齊。我們爲文字區域設定了彈性寬度(ub-f1),並指明當文字超出容器寬度時,自動縮略不換行(ut-s)。最後我們定義了一個圖片,這個圖片高(umh1)(umw1),採用ub-img控制其縮放,res1代表箭頭圖片,c-bla代表圖片區域默認背景色,uc-a使其有圓角,由於圖片寬度較小,配合圓角使其象一個圓形。這就是用彈性盒子佈局定義的一個帶圖標按鈕。那麼如何使圖標居於左側呢?彈性盒子模型的便利性在這裏有很好的體現。我們在容器中加入ub-rev類,它設定子元素反向排序,很簡單實現圖標居於左側。

<!--按鈕開始-->
<div ontouchstart="zy_touch('btn-act')" class="btn uba1 b-bla c-blu c-m1 uc-a ub t-wh uinn5 ub-ac ub-rev">
<div class="ub-f1 ut-s">
確定
</div>
<div class="umh1 umw1 ub-img res1 c-bla uc-a"></div>
</div>
<!--
按鈕結束-->

那如何使圖標上下佈局呢?一樣很簡單,只需要在容器中加入ub-ver,定義容器中的子元素縱向排序即可。

<!--按鈕開始-->
<div ontouchstart="zy_touch('btn-act')" class="btn uba1 b-bla c-blu c-m1 uc-a ub t-wh uinn5 ub-ac ub-ver">
<div class="ub-f1 ut-s">
確定
</div>
<div class="umh1 umw1 ub-img res1 c-bla uc-a"></div>
</div>
<!--
按鈕結束-->

通過上面的例子可以看到其實一個按鍵就是一個容器加一些子元素進行彈性盒子佈局,然後爲容器和子元素加一些控制和顯示效果。而其他控件也是這種方式,只是顯示效果定製上稍有不同罷了。

4.2 容器

UI2.0中我們認爲所有控件其實都是容器塊配合子容器和子元素組合。因此,容器是我們最基礎的組件之一。在應用開發中,經常需要把幾個按鈕、複選框或其他控件合併成一組進行顯示。在這種情況下一個滿足效果的容器將是必不可少的。我們接下來將講解,如何利用AppCan來構建一個容器並按照我們的想法對元素進行排列打開AppCan IDE(UI2.0),我們選擇中標紅的按鈕,進入容器製作嚮導。

可以看到容器分爲縱向排列容器和橫向排列容器。默認容器中會建立三個子元素,如果用戶需要自己控制子元素的話可以選擇無條目來建立一個空的容器。同時與按鍵控件相同,我們可以很簡單爲容器指定各種效果。我們接下來通過範例來演示如何使用容器。這次的範例是一個登陸的頁面

這個頁面中,縱向排列的兩個編輯區域用來演示縱向排列容器。兩個按鈕用於演示橫向排列。首先此頁面高度不會超過一個屏幕,因此我們不需要實現頁面的拖動。因此不需要建立一個浮動View來顯示內容區域,而可以直接在內容區域添加代碼。Demo008爲此範例的初始界面。我們在此基礎上進行調整來完成登陸頁面。Demo008範例首先在插入編輯區域和按鈕區域前,我們先對內容區域進行調整。content區域調整後的代碼

<div id="content" class="uinn2 c-org1 ub-f1"></div>

上述代碼中我們爲內容區域設定了橙色背景(c-org1),彈性區域(ub-f1)自動適配屏幕,最後設定其內邊距(uinn2),這樣可以使後面我們將要添加的元素不會緊貼內容區域邊界。準備完成後,我們在頁面中添加一個縱向排列容器。

<!--塊容器開始-->
<div class="ub ub-ver uba b-gra uc-a1 t-wh ">
<div class="ubb b-gra c-blu c-m1 uinn uc-t1">
條目
1</div>
<div class="ubb b-gra c-blu c-m1 uinn ">
條目
2</div>
<div class="c-blu c-m1 uinn uc-b1 ">
條目
3</div>
</div>
<!--
塊容器結束-->

我們構建了一個默認的帶三個條目的縱排塊容器。由於此範例中只需要兩個條目,且背景爲統一的白色背景,因此我們需要對生成的代碼進行調整,刪掉條目2,並去掉條目背景色,同時爲容器加上白色背景。修改後效果和代碼如下

<!--塊容器開始-->
<div class="ub ub-ver uba b-gra uc-a1 t-bla c-wh">
<div class="ubb b-gra uinn uc-t1">
條目
1</div>
<div class="uinn uc-b1 ">
條目
3</div>
</div>
<!--
塊容器結束-->

上圖我們可以看到,我們調整了容器的背景爲白色,字體色彩爲黑色,子條目沒有背景。這時我們就已經創建了一個符合要求的容器了。接下來,我們假如編輯框控件來替換條目1和條目3
我們先通過IDE中的編輯框嚮導

插入一個編輯框到條目1位置(選擇帶標籤),替換後的條目1部分代碼如下

<div class="ubb b-gra uinn uc-t1">
<!--
文本開始
-->
<div class="ub t-bla ulab"> <div class="uinn ulim">
標籤標籤
</div>
<div class="ub-f1 c-blu uba uc-a1 b-gra us-i uinput uinn4">
<input placeholder="hello" type="text" class="uc-a1">
</div>
</div><!--
文本開始
-->
</div>

目前的效果和我們需要的效果有些偏差我們需要調整一下。首先標籤部分不需要再有一個內邊距(uinn),其次編輯框也不需要有任何的背景邊框效果,我們刪掉這些類。調整後的效果如下

代碼:

<div class="ubb b-gra uinn uc-t1">
<!--
文本開始
-->
<div class="ub t-bla ulab ub-ac"> <div class="ulim">
用戶名
</div>
<div class="ub-f1 uinput uinn4">
<input placeholder="hello" type="text" class="uc-a1">
</div>
</div><!--
文本開始
-->
</div>

上面的代碼可以看到,對於一個編輯框,我們採用了彈性盒子模型,編輯區域通過ub-f1實現了寬度彈性變化。到此,我們完成了條目1部分的替換,接着我們拷貝這個代碼替換條目3。最終效果如下

這裏用到了一個小技巧,我們看到上面的圖示裏"用戶名:""密碼:"並不一樣長,造成標籤部分寬度不同,這會引起後面的編輯框區域寬度也不同,我們在"密碼:"後面添加了一箇中文空格來保證界面的排版。這是一個簡單但有效的方法。
下面我們再增加兩個按鈕。首先在編輯區域容器下方再構建一個橫向排列容器。

這個容器用來容納我們的那兩個按鈕。

<div class="ub uba b-gra c-blu c-m1 t-wh uc-a1 ">
<div class="ubr b-gra ub-f1 uinn uc-l1">
條目
1</div>
<div class="ubr b-gra ub-f1 uinn ">
條目
2</div>
<div class="ub-f1 uinn uc-r1">
條目
3</div>
</div>
</div>

建立好的容器只有兩個按鈕,也不需要任何背景。我們對模板進行刪減。
清理後的代碼如下

<!--塊容器開始-->
<div class="ub ">
<div class="ub-f1 uinn">
條目
1</div>
<div class="ub-f1 uinn">
條目
2</div>
</div>
</div>
<!--
塊容器結束-->

接着我們需要加入兩個按鈕來替換條目1和條目3的文字,通過IDE的按鍵控件嚮導我們插入兩個按鈕,通過高級模式調整好色彩,並修改文字色。

<!--塊容器開始-->
<div class="ub ">
<div class="ub-f1 uinn">
<!--
按鈕開始
-->
<div ontouchstart="zy_touch('btn-act')" class="btn uba b-gra uinn5 c-wh c-m1 uc-a t-bla">
確定
</div>
<!--
按鈕結束
-->
</div>
<div class="ub-f1 uinn">
<!--
按鈕開始
-->
<div ontouchstart="zy_touch('btn-act')" class="btn uba b-org uinn5 c-org c-m1 uc-a t-wh">
確定
</div>
<!--
按鈕結束
-->
</div>
</div>
<!--
塊容器結束-->

到此,我們完成了基本的界面排布。我們再稍微的調整一下幾個容器的間距即可。Demo009範例是調整完後的完整代碼。我們通過一個範例來展現了AppCan UI2.0中的容器的使用方法。目前我們看到不管是一個容器、一個按鈕或一個編輯框,都是依賴於彈性盒子模型實現的佈局。

4.3 編輯框

上一節呢,我們用到了編輯框,這裏我們對編輯框的使用作一個詳細的講解。AppCan UI2.0平臺提供了多種編輯框的默認效果。

有普通單行文本框、文本區域和搜索框。同時控件與按鍵控件一樣,也支持高級模式來定義效果。上一個例子裏我們使用了普通的編輯框,這個例子我們主要介紹搜索框和文本區域。
搜索框
一般搜索框常會用在標題下面,我們對index.html頁面做一下調整,在標題欄和內容區域之間插入一個搜索框。代碼如下

<!--文本開始-->
<form id="search" οnsubmit="alert('submit')">
<div class="t-bla ub uba uc-a b-gra us-i uinput ub-rev uinn4">
<div class="res6 umw1 ub-img ">
</div>
<div class="ub-f1 uinn1">
<input placeholder="search" type="text" class="" style="background:none;">
</div>
</div>
</form>
<!--
文本結束-->

上面代碼我們可以看到搜索框被放置到一個form表單裏,這樣手機的輸入法會根據輸入框的類型動態的匹配鍵盤效果。例如在鍵盤上確認按鈕顯示"搜索"等。由於在content區域前插入了搜索框,那麼下方構建浮動窗口的代碼中,浮動窗口位置也需要進行調整爲Header高度加上搜索框高度。

zy_con("content", "index_content.html", 0, $$("header").offsetHeight+$$("search").offsetHeight);
zy_resize("content",0,$$("header").offsetHeight+
$$("search").offsetHeight);

調整後的代碼見附件Demo0010範例
目前搜索框兩邊的圓角並沒有使其顯示成半圓形,我們只需要調整一下搜索框容器的uc-a類爲uc-a2即可,uc-a2是一個更大的圓角。最終效果如下

輸入域
接下來我們在index_content.html中添加一個輸入域。通過編輯框嚮導創建一個帶標籤的輸入域。

插入代碼後效果如下。

<!--文本開始-->
<div class="ub t-bla ulab">
<div class="uinn ulim">
標籤標籤

</div>
<div class="ub-f1 uba uc-a1 b-gra us-i uinput uinn4 ub ub-ver">
<textarea placeholder="hello" name="area1" class="uc-a1 ub-f1"></textarea>
</div>
</div>
<!--
文本結束-->

這裏呢我們希望標籤和輸入域縱向排列。很簡單,我們在容器後面加入ub-ver使子元素縱向排列。

<!--文本開始-->
<div class="ub t-bla ulab ub-ver">
<div class="uinn ulim">
標籤標籤

</div>
<div class="ub-f1 uba uc-a1 b-gra us-i uinput uinn4 ub ub-ver umh6">
<textarea placeholder="hello" name="area1" class="uc-a1 ub-f1"></textarea>
</div>
</div>

編輯框的高度我們添加umh6來控制,如果需要調整別的高度,可以在ui-base.cssumh6下方參照umh6定義自己的高度類,並替換上述代碼中的umh6即可。
我們對上面的代碼進行一個分析。
首先最外側是一個容器,這個容器採用彈性盒子架構(ub),定義了默認文本色(t-bla),由於有標籤,所以我們加入了標籤類(ulab),他主要控制標籤和編輯區域的橫向間距,如果縱向排列這個類可以刪除。容器中有兩個子元素,一個是標籤一個是子容器。標籤元素使用uinn爲齊添加內邊距,使用ulim來限制其長度。子容器用於定義編輯框的效果即陰影(us-i)、高度(umh6)、邊框(b-grauba)。爲了使輸入域與邊框間留下空隙,我們爲子容器加上內邊距(uinn4)uinput定義textarea元素的效果,ub定義此子容器依然是一個彈性盒子。由於輸入域在適配中的特殊性,我們爲子容器定義ub-ver,要求妻子元素縱向排列。接着我們爲textarea指定ub-f1,使其撐滿整個容器內邊距內區域。最後的代碼看附件Demo011範例

4.4 下拉列表控件

下拉列表控件經常用於在有限的區域內實現單選效果或多選,這個控件在應用開發中非常常見。我們對select標籤進行了封裝,使其有可定製化的現實效果。打開AppCan IDE(UI2.0),我們選擇中標紅的按鈕,進入下拉列表製作嚮導。

下拉列表同之前的控件一樣,可以通過高級模式配置效果。我們建立一個帶標籤的下拉列表,並對其代碼進行講解。Demo012範例
效果:

代碼:

<!--下拉列表開始-->
<div class="ub t-bla">
<div class="uinn ulim">
標籤標籤
</div>
<div class="ub-f1 ub uba uc-a1 c-wh b-org us-i sel"> 
<div class="ub-f1 ut-s uinn ulev-1 tx-l">
下拉列表
</div> 
<div class="ubl b-org c-red c-m2 umw2 ub ub-pc uc-r2 ub-ac"> 
<div class="ub-img umw1 umh1 res3"></div> 
</div> 
<select name="sel0" selectedindex="0" id="sel0" οnchange="zy_slectmenu(this.id)"> 
<option>item1</option> 
<option>item2</option> 
<option>item3</option> 
<option>item4</option> 
</select> 
</div>
</div> 

上面代碼中,我們可以看到這個控件是由一個容器中包含的標籤部分和下拉列表部分組成。下拉列表中又分三個部分:
  文字區域-用於顯示選中的條目內容

  按鈕區域-是一個容器包含一個下箭頭的圖標。這個圖標通過彈性盒子進行居中顯示
  ■Select控件-是一個與整個下拉列表容器等高寬的透明控件,這樣用戶看到的是我們的文字區域和按鈕區域,但實際點擊時,點擊的是系統Select控件。在select控件中我們通過zy_selectmenu接口截取用戶選中的條目,修改文字區域內容
上述控件中,不管是最外面的容器還是子容器,我們都使用的是彈性盒子模型。

4.5 導航欄

在應用開發中,導航欄是組織內容的一種常見方式。它可以給用戶更直觀的選擇和良好的交互體驗。AppCan IDE UI2.0)框架對UI1.0中的導航欄控件進行了調整,使用新的彈性盒子模型重新構建了代碼,更加便於開發者進行調整定製。我們通過選擇IDE控件欄中標紅的按鈕,來構建一個導航欄。導航欄也可使用高級模式來設定背景色和漸變。我們在index.html中的footer部分構建一個導航欄。Demo013範例
效果:

代碼:

<!--iPhone導航條開始-->
<div class="ub c-bla c-m1 tab t-wh">
<input class="uhide" type="radio" name="tabSwitch" checked="true">
<div ontouchstart="zy_touch('',zy_for)" class="ub-f1 ub ub-ver tab-act"><div class="ub-f1 ub-img5 tp-info"></div><div class="uinn ulev-2 tx-c">
新聞
</div></div>
<input class="uhide" type="radio" name="tabSwitch">
<div ontouchstart="zy_touch('',zy_for)" class="ub-f1 ub ub-ver tab-act"><div class="ub-f1 ub-img5 tp-home"></div><div class="uinn ulev-2 tx-c">
新聞
</div></div>
<input class="uhide" type="radio" name="tabSwitch">
<input class="uhide" type="radio" name="tabSwitch">
<div ontouchstart="zy_touch('',zy_for)" class="ub-f1 ub ub-ver tab-act"><div class="ub-f1 ub-img5 tp-set"></div><div class="uinn ulev-2 tx-c">
新聞
</div></div>
<input class="uhide" type="radio" name="tabSwitch">
<div ontouchstart="zy_touch('',zy_for)" class="ub-f1 ub ub-ver tab-act"><div class="ub-f1 ub-img5 tp-shop"></div><div class="uinn ulev-2 tx-c">
新聞
</div></div>
<input class="uhide" type="radio" name="tabSwitch">
<div ontouchstart="zy_touch('',zy_for)" class="ub-f1 ub ub-ver tab-act"><div class="ub-f1 ub-img5 tp-talk"></div><div class="uinn ulev-2 tx-c">
新聞
</div></div>
</div>

上述代碼可以看到,整個導航欄是由一個彈性盒子容器包含5個條目組成的,如果用戶需要事先大於5個或小於5個的導航欄,只需要拷貝複製或刪除條目即可。每個條目又是由一個radiobox控件和一個縱排的彈性盒子子容器組成。在子容器中,包含圖片和文字兩個子元素。我們對這些組成部分進行一下分析。
  ■radiobox控件-此控件爲隱藏控件,並不現實(uhide),他的作用是通過和其他具有同樣name屬性的radiobox控件組合使用,來實現條目的單項選擇,配合後面子元素的CSS類屬性實現選中和未選中效果。
  子容器-用於容納每一個條目的子元素。同時負責顯示選中和未選中狀態(tab-act)。我們看一下ui-tab.csstab-act的定義。

input[type="radio"]:checked + div.tab-act
{
background-color:rgba(255,255,255,0.1) !important;
border-radius:0.3em;
border: 0px;
background-image: none;
}

  上面代碼可以很清晰的看到當一個radiobox 被選中狀態下,他相鄰的那個div中的tab-act類表示一個透明度爲0.1的圓角矩形。未選中狀態下無效果。通過這個類配合之前的單選鈕我們可以很簡單的實現條目的選中未選中狀態變化。
  圖片元素-用於顯示每一個條目得圖片(tp-info)。由於每個條目的圖片不同,需要爲每個圖片元素設定圖片資源。目前我們在ui-tab.css中預置了六組圖片資源類,用戶可以根據需求替換相應的圖片資源。每一組圖片資源分選中狀態和爲選中狀態,我們以tp-info爲例進行分析。

input[type="radio"] + div>div.tp-info{
background: url(res-apple/info.png) 50% 50% no-repeat;
}

input[type="radio"]:checked + div>div.tp-info{
background: url(res-apple/info-act.png) 50% 50% no-repeat;
}

  上述代碼中,可以看到當一個radio未選中時,與他相鄰的div中的子div元素具有的tp-info屬性對應背景圖片爲info.png。當選中時,與他相鄰的div中的子div元素具有的tp-info屬性對應背景圖片爲info-act.png。即配合radiobox我們可以簡單的實現圖片的變化。
導航欄並不一定都是這種顯示效果,我們修改一下代碼實現以下另一種效果。

這是上面是中文下方是英文的效果。附件是代碼Demo014範例。我們調整了子容器的元素,從一個圖片變爲了兩組文字框。

<div ontouchstart="zy_touch('',zy_for)" class="ub-f1 ub ub-ver tab-act"><div class="uinn3 tx-c">新聞</div><div class="uinn ulev-1 tx-c">news</div></div>

上面展示的良種效果會有些問題,我們可以看到每一個子容器都是通過ub-f1進行等分的,但在文章最開始我們介紹時提到過,如果自容器中的內容並不等長時,瀏覽器會動態的調整每個字元素的寬度即時齊都是相同的flex屬性。如果確實出現了文字不等長的情況,我們該如何調整呢?我們調整一下Demo014範例的代碼Demo015範例

<div ontouchstart="zy_touch('',zy_for)" class="ub-f1 ub ub-ver tab-act uinn3">
<div class="tx-c umh2 umar-b umar-t">
<div class="ub-con ulev-1 ut-s">
早間新聞
</div>
</div>
<div class="ulev-1 tx-c umh1">
<div class="ub-con">news</div>
</div>
</div>

相對於之前,修改後我們爲文字外添加了一個容器,通過ub-con定義此文字區域的高寬與父元素相同。而之前每一個文字區域的高度都是被文字撐開的,所以此時爲了保證文字區域的高度,我們分別爲兩個文字區域設定了umh2umh1的最小高度值。由於ub-con定義使用了position:absoluteheight:100%屬性,則其高度是父容器的邊框高+內邊距高+內容高,因此我們不能爲原來的文字區域再指定內邊距,我們爲條目容器指定了uinn3的內邊距來代替原來爲文字區域設定的uinn3,通過爲上方的文字區域指定上下外邊界來爲兩個文字區域進行分隔。通過這種寫法,我們可以在各條目文字長度不同的情況下保持寬度的一致。同樣,在頁面設計中ub-con也可以用到其它有類似問題的地方。
導航條的目的是爲了配合頁面的切換。那麼下面我們演示一下如何通過導航條快速實現頁面切換。我們目前已經有了一個index.html和一個index_content.html,那麼我們爲index.html頁面在建立一個內容頁面。複製index_content.html,改名爲msg_content.html。這個時候我們就有了兩個內容頁面。我們在script區域添加兩個函數

function loadmsgcontent(){
zy_con("content", "msg_content.html", 0, $$("header").offsetHeight);
}
function loadindexcontent(){
zy_con("content", "index_content.html", 0, $$("header").offsetHeight);
}

第一個函數用於修改名字爲content的浮動窗口加載的頁面爲msg_content.html,第二個函數用於修改content浮動窗口加載的頁面爲index_content.html。然後我們爲導航欄中第一個元素和第二個元素分別加上onclick事件,

<div ontouchstart="zy_touch('',zy_for)" οnclick="loadindexcontent()" class="ub-f1 ub ub-ver tab-act uinn3">
<div class="tx-c umh2 umar-b umar-t">
<div class="ub-con ulev-1 ut-s">
早間新聞
</div>
</div>
<div class="ulev-1 tx-c umh1">
<div class="ub-con">news</div>
</div>
</div>
<div ontouchstart="zy_touch('',zy_for)" οnclick="loadmsgcontent()" class="ub-f1 ub ub-ver tab-act uinn3">
<div class="tx-c umh2 umar-b umar-t">
<div class="ub-con ulev-1 ut-s">
新聞
</div>
</div>
<div class="ulev-1 tx-c umh1">
<div class="ub-con">news</div>
</div>
</div>

此時我們可以看到,當我們點擊第一個條目和第二個條目時,中間區域的網頁內容發生了改變。範例工程參閱附件Demo016範例

4.6 單選框和複選框

單選和複選框是應用中常見的組件,他們一般都會按組的方式實現。我們通過IDE中標紅的兩個按鈕來生成複選和單選控件。我們打帶複選框嚮導

構建一個單個複選框按鈕,並對其代碼進行分析

代碼:

<!--複選框開始-->
<input type="checkbox" name="che1" class="uhide" checked="checked" value=""> 
<div οnclick="zy_for(event)" ontouchstart="zy_touch('btn-act')" class="ub uc-a1 uba c-gra c-m2 b-gra t-bla uinn5 ">
<div class="ub-f1 ut-s tx-l" >item</div>
<div class="che-icon ub-img umw1"></div> 
</div>
<!--
複選框結束-->

述代碼可以看到一個複選框由一個隱藏(uhide)checkbox和一個複選框容器組成。複選框容器包含一個文字區域和一個選中狀態圖標。當用戶點擊這個複選框容器時觸發onclick函數,會調用zy_for函數,此函數會對這個DIV元素之前的Input標籤的checked屬性做取反操作,即如果checkedtrue則變爲false,爲false則變爲true。與之前select和導航欄控件機制一樣,我們通過input和後面元素的CLASS類組合通過input的狀態變化達到更換選中狀態圖標的效果。我們可以看一下che-icon這個類的定義。

input[type=checkbox]+div>div.che-icon {
background-color: transparent;
background-image: url(images/icons-18-white_39.png);
}
input[type=checkbox]:checked+div>div.che-icon {
background-color: transparent;
background-image: url(images/icons-18-white_37.png);
}

上述代碼種,當input被選中時,其相鄰的div中的子Div元素的che-icon屬性會設定圖片爲icons-18-white_37.png。如果未選中則設定爲icons-18-white_39.png。通過這裏我們可以看到,我們在控件中廣泛採用了input和類進行組合的方式非常簡單的實現各種效果。
複選框還有一種變形,我們看看如下範例Demo017範例,通過嚮導選擇

index_contet.html中添加一個水平分組複選框。效果如下

代碼:

<!--複選框開始-->
<div class="ub uc-a1 t-bla c-gra c-m2 uba b-gra tx-c"> 
<input type="checkbox" name="che1" class="uhide" value=""> 
<div οnclick="zy_for(event)" class="uinn5 ubr b-gra uc-l1 ub-f1 che">item</div> 
<input type="checkbox" name="che2" class="uhide" value=""> 
<div οnclick="zy_for(event)" class="uinn5 ubr b-gra ub-f1 che">item</div> 
<input type="checkbox" name="che3" class="uhide" value=""> 
<div οnclick="zy_for(event)" class="uinn5 uc-r1 ub-f1 che">item</div>
</div>
<!--
複選框結束-->

水平復選框分組其實就是一個容器包含了三個子元素,每個子元素配合一個input標籤來控制其效果(che)。我們看一下che類的代碼

input[type=checkbox]:checked+div.che {
box-shadow:inset 0 1px 2px rgba(0,0,0,0.6);
}

上述代碼表示當input被選中時,爲元素添加一個內陰影。
對於縱向排列的複選框分組就不作介紹了,大家可以自己通過模板建立一個,研究一下代碼。它其實就是一個容器裏放了多個單條複選框而已。
單選框和複選框基本代碼和設計都是一致的只是單選框的隱藏input標籤類型爲radio而已。大家可以研究一下ui-input.css中的類定義

4.7 列表控件

有人說80%的應用界面都是列表形式的,沒統計過但是從大概的感覺上可以認爲沒有什麼偏差。AppCan IDE UI(2.0)中,提供了新構建的列表模板。我們通過IDE中的列表嚮導進行構建Demo018範例

這次我們構建一個帶圖標的列表。
效果:

代碼:

<!--列表開始-->
<div class="uba b-gra c-wh us uc-a ">
<div ontouchstart="zy_touch('btn-act')" class="uc-t ubb c-m2 ub b-gra t-bla ub-ac lis">
<div class="lis-icon ub-img im"></div>
<div class="ub-f1 ut-s">
設置
</div>
<div class="tx-r t-blu ulev-1">Old Phone</div>
<div class="res8 lis-sw ub-img"></div>
</div>
<div ontouchstart="zy_touch('btn-act')" class=" ub ubb b-gra c-m2 t-bla ub-ac lis">
<div class="lis-icon ub-img im"></div>
<div class="ub-f1 ut-s">
設置
</div>
<div class="tx-r t-blu ulev-1">Old Phone</div>
<div class="res8 lis-sw ub-img"></div>
</div>
<div ontouchstart="zy_touch('btn-act')" class="uc-b c-m2 ub t-bla ub-ac lis">
<div class="lis-icon ub-img im"></div>
<div class="ub-f1 ut-s">
設置
</div>
<div class="tx-r t-blu ulev-1">Old Phone</div>
<div class="res8 lis-sw ub-img"></div>
</div>
</div>
<!--
列表結束-->

這是一個三個條目的列表,很明顯,這個列表與其他控件基本組成元素都是一致的,也是一個容器、子容器加一些元素構造而成。我們主要對一個條目進行講解。

<div ontouchstart="zy_touch('btn-act')" class="uc-t ubb c-m2 ub b-gra t-bla ub-ac lis">
<div class="lis-icon ub-img im"></div>
<div class="ub-f1 ut-s">
設置
</div>
<div class="tx-r t-blu ulev-1">Old Phone</div>
<div class="res8 lis-sw ub-img"></div>
</div>

這是列表的第一個條目,我們一行一行進行解析。

<div ontouchstart="zy_touch('btn-act')" class="uc-t ubb c-m2 ub b-gra t-bla ub-ac lis">

這是一個容器,由於是第一行,所以他的圓角要和外面容器的圓角保持匹配,因此我們爲其設定圓角(uc-t),這個容器和下一行需要一條分割線,我們設定這個子容器右下邊界(ubb),邊界色彩爲(b-gra),這個條目有一點簡便效果,我們採用的是(c-m2)由於其位於容器內,這個遮蓋層會和父容器背景色進行組合。這個子容器包含多個元素,這些元素也是以彈性盒子模型進行排版(ub),文字色彩定義爲黑色(t-bla),由於容器中的子元素高低不定,因此我們要求其子元素中線對其(ub-ac)。最後是設定列表條目的默認效果(lis 建立了內邊距)

<div class="lis-icon ub-img im"></div>

這是容器中的第一個元素,它是一個小圖片,我們設定了這個圖片的高寬(lis-icon),同時設定了這個圖片是(im),圖片的展示參數通過(ub-img)來設定。 備註:
默認工程中的ui-img.css定義了我們範例中的範例資源圖片,而ui-res.css是我們控件需要的資源圖片。

<div class="ub-f1 ut-s">設置</div>

這一行設定了一個彈性區域,他會撐滿真個容器的空閒區域(ub-f1),當文字長度超過可容納區域後,進行縮略(ut-s)

<div class="tx-r t-blu ulev-1">Old Phone</div>

這一行定義了一個文字去,這個文字區的大小會根據文字長度進行調整。我們通過ulev-1對此地的文字進行縮小顯示。並通過t-blu設定其顏色爲蘭色。

<div class="res8 lis-sw ub-img"></div>

最後這個元素是一個小箭頭圖標。lis-sw定義了他的大小,res8指定了所用的資源,ub-img定義了圖片的展示方式。
通過這部分解析我們看到一個列表其實也是由最基本的容器和元素組合而成。通過彈性盒子模型,真個列表的排佈會非常簡潔明瞭。

4.8 開關按鈕

UI2.0框架中,我們對開關按鈕進行了重新實現,配合上一個範例,我們在第一個條目中插入開關按鈕來體驗一下他的效果。Demo019範例

代碼:

<div ontouchstart="zy_touch('btn-act')" class="uc-t ubb c-m2 ub b-gra t-bla ub-ac lis">
<div class="lis-icon ub-img im"></div>
<div class="ub-f1 ut-s">
設置
</div>
<!--
開關按鈕開始
-->
<input class="uhide" type="checkbox" checked="true" >
<div class="uba b-gra swi swi-bg uc-a1" οnclick="zy_for(event)"></div>
<!--
開關按鈕結束
-->
</div>

上面代碼中,我們把前一個範例的第一個條目後面的兩個元素刪除,替換了一個開關按鈕。開關按鈕的動畫變換也是依賴於input的變化進行控制。其中swi定義了這個控件的變形動畫效果,swi-bg定義了這個開關按鈕的背景swiinput進行配合定義了不同狀態下的效果。

input[type=checkbox]:checked + div.swi{
background-position:-0.1em;
}
input[type=checkbox] + div.swi
{
background-position:-4.01em
}

input標籤被選中時,swi的背景位置是-0.3em。當未被選中時,背景位置爲-4.01em。通過背景圖片位置的變化完成選中狀態的變化。
通過上面的講解,我們展示了UI2.0的框架設計思想。並通過對我們預置組件代碼的分析,使大家對如何使用UI2.0框架調整界面有了一個基本的認識。我們總結一下我們公司開發人員的UI設計規則
1.
製作前先考慮好如何組織頁面,需要如何佈局,在什麼地方需要幾個容器來進行排版。然後構建架子,使用默認效果類進行排版定位和美化
2.
如果需要使用顏色,請在ui-color.css中根據文本、背景、遮蓋、邊框等分別擴展自己的類定義
3.
如果需要調整圓角、邊距等附加屬性請在ui-base.css中進行添加。
4.
如果需要資源,請在ui-res.css中進行擴展
5.
如果需要佈局,請在ui-box.css中進行調整
6.
所有調整要遵循默認的命名規則。
遵守這些規則可以使你的代碼更容易被其他人閱讀,代碼複用和調整將會更加簡單

 

發佈了19 篇原創文章 · 獲贊 5 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章