頭條的案例算是一個經典的案例,私底下也稱為Feeds
類應用,該類應用有一個特點,那就是一個頁面會顯示很多條Feed
,不同的Feed
對應不同的模板,也就是不同的(UITableViewCell子類)
,並且每個模板的高度是不固定的,有些模板中的文字需要適當換行顯示
,有些模板中的圖片需要按照比例顯示
,並且還要考慮不同裝置的適配,甚至還要考慮在螢幕橫豎屏切換的情況,以上種種加一起來,做這樣的應用相當的複雜。事實上,還有一種情況更加的棘手,那就是不同的app版本可能支援的模板種類不一樣,比如在新的版本中加入了新的模板,那麼對於老版本就無法顯示了,不過這個問題這裡就不做深入介紹了,你可以參考熱更新
一章來獲得靈感?。
文章中貼出的XML程式碼你可以直接從git下載並且執行檢視效果,git下載地址
現在就拿今日頭條來做下案例分析,如下面三張圖所示:
圖1 | 圖2 | 圖3 |
---|
上面一共7種不同的模板。下面一一進行分析。
整體分析
從上面7中不同的模板可以歸類出有兩種基礎的佈局模板。
-
模板1、2、3、4使用的模板歸為一類,分為上下兩層,上面一層是新聞內容,下面顯示該條新聞出處、評論、時間內容,而只有第一層新聞內容那一層是會改變的。那麼就可以定義一個基礎模板。
<!--基礎模板1--> <template t-name="base1"> <stack-panel> <!-- 佔位模板,新聞內容 --> <template-slot slot-name="content" space-before="10" /> <!--底部資訊--> <stack-panel is-horizon="1" space="10" space-before="10" space-after="10"> <lable text="人民網" font-color="999999" /> <lable text="15評論" font-color="999999" /> <lable text="1小時前" font-color="999999" /> </stack-panel> </stack-panel> </template> 複製程式碼
注意到上面使用了
template-slot
用來佔位,這樣不同模板的新聞內容就可以通過template-slot
來顯示了。另外,將該佔位名稱設為content
,對應slot-name="content"
。事實上,一個模板中,你可以定義N個
template-slot
,只需要slot-name
唯一即可。 -
模板5、6、7使用的模板歸為第二類,該類别範本分三層,上面一層是使用者資訊,第二層是新聞內容,第三層是贊、評論、分享數量等資訊的顯示。同樣的只有中間第二層的新聞內容會改變的,第一層和第三層是不會改變的。
<!--基礎模板2 (帶使用者資訊)--> <template t-name="base2"> <stack-panel> <!-- 使用者資訊 --> <stack-panel is-horizon="1" space-before="10" space="10"> <image size="32" corner-radius="16" url="http://imgtu.5011.net/uploads/content/20170504/5905661493879766.jpg" /> <!-- 佔用中間全部剩餘空間 --> <stack-panel flex-grow="1" flex-shrink="1"> <lable text="海偉22" font-size="14" font-color="191919" /> <lable text="碼農" font-color="999999" /> </stack-panel> <!-- 右邊的關注按鈕 --> <dock-panel width="50"> <lable text="關注" font-color="red" font-size="14" /> </dock-panel> </stack-panel> <!-- 佔位模板,新聞內容 --> <template-slot slot-name="content" space-before="10" /> <!--底部資訊--> <grid-panel columns="3" space-before="10" space-after="10"> <stack-panel is-horizon="1" justify-content="1" space="5" align-items="2"> <image local-name="zan" size="15" /> <lable text="21" font-color="191919" /> </stack-panel> <stack-panel is-horizon="1" justify-content="1" space="5" align-items="2"> <image local-name="zan" size="15" /> <lable text="49" font-color="191919" /> </stack-panel> <stack-panel is-horizon="1" justify-content="1" space="5" align-items="2"> <image local-name="zan" size="15" /> <lable text="60" font-color="191919" /> </stack-panel> </grid-panel> </stack-panel> </template> 複製程式碼
同樣的,上面的模板一樣使用了
template-slot
用來佔位。
模板分析
下面開始一一分析7個不同的模板,7種模板都是基於上面定義的兩個基礎模板進行開開發的,你可以理解為類的繼承
關係。
模板1
模板1的內容很簡單,就是顯示新聞標題。並且不限制行數。
<!--feed模板1文字模板-->
<template t-name="t1">
<!-- 基於base1開發 -->
<template-ref t-name="base1">
<!-- 模板佔位 slot-name="content" -->
<lable text="國際社會積極評價習近平主席在金磚國家工商論壇上的重要講話" slot-name="content" font-color="191919" font-size="24" />
</template-ref>
</template>
複製程式碼
- 該模板是基於
base1
模板進行開發的,這種方式叫做模板巢狀
。類似於類的繼承
。- 注意上面的
slot-name="content"
,將base1
模板中的template-slot
替換成lable
。
模板2
模板2的內容為標題+圖片,並且圖片最多顯示三張,並且圖片按照寬高比16:9進行顯示。
<!--feed模板2,文字加圖片,圖片16:9顯示-->
<template t-name="t2">
<!-- 基於base1開發 -->
<template-ref t-name="base1">
<!-- 佔位內容 -->
<stack-panel slot-name="content">
<lable text="國際社會積極評價習近平主席在金磚國家工商論壇上的重要講話" font-color="191919" font-size="24" />
<!-- 使用grid-panel佈局,每行三列,並且列間距10 -->
<grid-panel columns="3" space-before="10" data-context="[1,2,3]" column-spacing="10">
<for>
<!-- 寬高比例16:9 -->
<ratio-panel ratio="0.5625">
<image url="http://img5.duitang.com/uploads/item/201204/01/20120401222440_eEjyC.thumb.700_0.jpeg" />
</ratio-panel>
</for>
</grid-panel>
</stack-panel>
</template-ref>
</template>
複製程式碼
模板3
模板3的內容為左邊是標題,右邊是圖片,並且圖片的寬度佔行寬的32%,並且圖片的寬高比例16:9。
<!--feed模板3,文字加圖片,圖片16:9顯示,寬度為50%cell寬度-->
<template t-name="t3">
<!-- 基於base1開發 -->
<template-ref t-name="base1">
<!-- 佔位內容 -->
<stack-panel slot-name="content" is-horizon="1">
<!-- 左邊標題,使用flex-grow="1" flex-shrink="1"屬性將左邊的內容全部佔用 -->
<lable text="國際社會積極評價習近平主席在金磚國家工商論壇上的重要講話" flex-grow="1" flex-shrink="1" font-color="191919" font-size="24" />
<!-- 圖片寬度為行寬的32%,並且寬高比為16:9,跟lable的間距為10 -->
<ratio-panel width="32%" ratio="0.5625" space-before="10">
<image url="http://img5.duitang.com/uploads/item/201204/01/20120401222440_eEjyC.thumb.700_0.jpeg" />
</ratio-panel>
</stack-panel>
</template-ref>
</template>
複製程式碼
模板4
模板4的內容為上面是標題,下面是圖片,圖片寬高按照16:9顯示。標題最多顯示3行。
<!--feed模板4-->
<template t-name="t4">
<!-- 基於base1開發 -->
<template-ref t-name="base1">
<!-- 佔位內容 -->
<stack-panel slot-name="content">
<lable text="國際社會積極評價習近平主席在金磚國家工商論壇上的重要講話" font-color="191919" font-size="24" lines="3" />
<ratio-panel ratio="0.5625" space-before="10">
<image url="http://img5.duitang.com/uploads/item/201204/01/20120401222440_eEjyC.thumb.700_0.jpeg" />
</ratio-panel>
</stack-panel>
</template-ref>
</template>
複製程式碼
模板5
模板5的內容為上面是標題,下面是圖片,寬度固定200。寬高比例為16:9
<!--feed模板5-->
<template t-name="t5">
<!-- 基於base2開發 -->
<template-ref t-name="base2">
<!-- 佔位內容 -->
<stack-panel slot-name="content">
<!-- 標題,最多顯示3行 -->
<lable text="國際社會積極評價習近平主席在金磚國家工商論壇上的重要講話" font-color="191919" font-size="24" lines="3" />
<ratio-panel ratio="0.5625" space-before="10" width="200">
<image url="http://img5.duitang.com/uploads/item/201204/01/20120401222440_eEjyC.thumb.700_0.jpeg" />
</ratio-panel>
</stack-panel>
</template-ref>
</template>
複製程式碼
模板6
模板6的內容其實跟模板2的內容是一樣的。只是使用的基礎模板不同而已。
<!--feed模板6-->
<template t-name="t6">
<!-- 基於base2開發 -->
<template-ref t-name="base2">
<!-- 佔位內容 -->
<stack-panel slot-name="content">
<lable text="國際社會積極評價習近平主席在金磚國家工商論壇上的重要講話" font-color="191919" font-size="24" lines="3" />
<!-- 使用grid-panel佈局,每行三列,並且列間距10 -->
<grid-panel columns="3" column-spacing="10" space-before="10" data-context="[1,2,3]">
<for>
<ratio-panel ratio="0.5625">
<image url="http://img5.duitang.com/uploads/item/201204/01/20120401222440_eEjyC.thumb.700_0.jpeg" />
</ratio-panel>
</for>
</grid-panel>
</stack-panel>
</template-ref>
</template>
複製程式碼
模板7
模板7的內容上面是標題,下面是新聞的引用。左邊圖片,右邊是新聞的描述,新聞描述最多顯示兩行,並且垂直居中顯示。
<!--feed模板7-->
<template t-name="t7">
<!-- 基於base2開發 -->
<template-ref t-name="base2">
<!-- 佔位內容 -->
<stack-panel slot-name="content">
<!-- 標題,最多顯示三行 -->
<lable text="國際社會積極評價習近平主席在金磚國家工商論壇上的重要講話" font-color="191919" font-size="24" lines="3" />
<!-- 新聞描述水平顯示,並且垂直方向居中顯示。 -->
<stack-panel is-horizon="1" space-before="10" space="10" align-items="2" background-color="efefef">
<!-- 圖片寬度80,並且寬高4:3 -->
<ratio-panel width="80" ratio="0.75">
<image url="http://img5.duitang.com/uploads/item/201204/01/20120401222440_eEjyC.thumb.700_0.jpeg" />
</ratio-panel>
<!-- 最多顯示兩行,並且佔用剩餘的全部空間 -->
<lable text="環球網:中國巴基斯坦加油!會哭會的哈哈但是上帝大大所大多撒多掃地哈哈是的哈哈" flex-grow="1" flex-shrink="1" font-size="14" lines="2" />
</stack-panel>
</stack-panel>
</template-ref>
</template>
複製程式碼
顯示模板
上面的模板介紹完了,那麼下面就需要將模板顯示出來了。因為不同的feed資料需要不同的模板來顯示,那麼就必須使用資料繫結
來實現了。
<!-- UITableView -->
<list>
<section>
<for data-path="items">
<!-- UITableViewCell -->
<list-item>
<!-- 新聞內容的內邊距為左右間距12,上下間距0 -->
<inset-panel inset="0 12">
<!-- 通過資料繫結選擇模板 -->
<template-ref t-name="{{}}"></template-ref>
</inset-panel>
</list-item>
</for>
</section>
</list>
複製程式碼
demo用的資料內容。
class Index {
constructor() {
this.items = [
"t1", "t2", "t3", "t4", "t5", "t6", "t7",
"t1", "t2", "t3", "t4", "t5", "t6", "t7",
"t1", "t2", "t3", "t4", "t5", "t6", "t7"];
}
}
複製程式碼
這樣就能一次性顯示出21條資料。包含三種模板,陣列中的字串表示的就是模板名稱。
上面所有的模板程式碼包括註釋
也就180行程式碼,如果使用傳統方式開發的話,你自己可以評估下開發工作量。