iOS混合開發庫(GICXMLLayout)佈局案例分析(1)今日頭條案例

搬磚的碼農發表於2019-01-08

頭條的案例算是一個經典的案例,私底下也稱為Feeds類應用,該類應用有一個特點,那就是一個頁面會顯示很多條Feed,不同的Feed對應不同的模板,也就是不同的(UITableViewCell子類),並且每個模板的高度是不固定的,有些模板中的文字需要適當換行顯示,有些模板中的圖片需要按照比例顯示,並且還要考慮不同裝置的適配,甚至還要考慮在螢幕橫豎屏切換的情況,以上種種加一起來,做這樣的應用相當的複雜。事實上,還有一種情況更加的棘手,那就是不同的app版本可能支援的模板種類不一樣,比如在新的版本中加入了新的模板,那麼對於老版本就無法顯示了,不過這個問題這裡就不做深入介紹了,你可以參考熱更新一章來獲得靈感?。

文章中貼出的XML程式碼你可以直接從git下載並且執行檢視效果,git下載地址

iOS混合開發庫(GICXMLLayout)佈局案例分析(1)今日頭條案例

現在就拿今日頭條來做下案例分析,如下面三張圖所示:

iOS混合開發庫(GICXMLLayout)佈局案例分析(1)今日頭條案例
圖1
iOS混合開發庫(GICXMLLayout)佈局案例分析(1)今日頭條案例
圖2
iOS混合開發庫(GICXMLLayout)佈局案例分析(1)今日頭條案例
圖3

上面一共7種不同的模板。下面一一進行分析。

整體分析

從上面7中不同的模板可以歸類出有兩種基礎的佈局模板。

  1. 模板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唯一即可。

  2. 模板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

iOS混合開發庫(GICXMLLayout)佈局案例分析(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>
複製程式碼
  1. 該模板是基於base1模板進行開發的,這種方式叫做模板巢狀。類似於類的繼承
  2. 注意上面的slot-name="content",將base1模板中的template-slot替換成lable

模板2

iOS混合開發庫(GICXMLLayout)佈局案例分析(1)今日頭條案例






模板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

iOS混合開發庫(GICXMLLayout)佈局案例分析(1)今日頭條案例







模板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

iOS混合開發庫(GICXMLLayout)佈局案例分析(1)今日頭條案例

模板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

iOS混合開發庫(GICXMLLayout)佈局案例分析(1)今日頭條案例

模板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

iOS混合開發庫(GICXMLLayout)佈局案例分析(1)今日頭條案例

模板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

iOS混合開發庫(GICXMLLayout)佈局案例分析(1)今日頭條案例

模板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行程式碼,如果使用傳統方式開發的話,你自己可以評估下開發工作量。

相關文章