四核驅動的三維導航—淘寶新UI(設計篇)

来源:http://www.cnblogs.com/ms-uap/archive/2016/06/07/5543180.html
-Advertisement-
Play Games

前面有一篇博客說到了淘寶UWP的"四核驅動的三維導航—淘寶新UI(需求分析篇)",花了兩周的時間實現了這個框架,然後又陸陸續續用了三周的時間完善它。 多視窗導航,與傳統的導航方式的最大的不同點是: 本篇博客先說一下前三個問題如何解決。 在從頁面A跳到頁面B時,單視窗模式下,很簡單,只要在頁面A中調用 ...


前面有一篇博客說到了淘寶UWP的"四核驅動的三維導航—淘寶新UI(需求分析篇)",花了兩周的時間實現了這個框架,然後又陸陸續續用了三周的時間完善它。

多視窗導航,與傳統的導航方式的最大的不同點是:

  1. 需要指定目標視窗(target Frame)
  2. 維護上下文關係(context)
  3. Back Stack的維護
  4. 頁面間的非同步通信
  5. 適配Desktop和Mobile界面
  6. 支持Continuum(optional)

本篇博客先說一下前三個問題如何解決。

在從頁面A跳到頁面B時,單視窗模式下,很簡單,只要在頁面A中調用系統方法就可以了:

this.Frame.NavigateTo(typeof (PageB));

因為頁面A使用的Frame和頁面B使用的Frame相同。但是在多視窗(多Frame)時,你需要指定頁面B使用那個Frame作為目標視窗。

比如,淘寶首頁:

在點擊了"淘搶購"頻道的入口後,你想在什麼地方顯示淘搶購的主頁面呢?在目前的Taobao UWP中,我們選擇在主頁的右側顯示(但是考慮到淘搶購的使用頻率,我們可能會考慮在下一版中把它作為一個獨立的Scenario來對待,也就是說可能要在目前的主頁的位置顯示)。於是,界面就會變成這樣:

這就要求在導航方法中多一個參數來指定具體的位置。按照我們的設計,在Taobao UWP中有以下4個Frame承擔具體的導航工作:

Home Frame:作為一個Scenario的首頁,必須存在。

List Frame:顯示商品列表,可以存在。有些Scenario,它的首頁就是一個商品列表,就在Home Frame里顯示了,List Frame可以不存在。

Detail Frame:詳情頁,必須存在。基本上所有的商品,都是要通過詳情頁來展示具體的商品信息的。當然,在別的Scenario中,如"我的淘寶"場景,可以用此Frame顯示別的非商品內容。

Chat Frame:附加頁,一般用於顯示內置旺信聊天視窗,必須存在。

 

淘寶首頁是顯示在Home Frame中的,點擊淘搶購入口後,code里都做了什麼壞事兒呢?

Nav.To(NavToUrls.RushBuy_Home, mode: NavMode.List_Replace);

其中,Nav是我們自定義的一個導航幫助類,To()是它的靜態方法,定義如下:

public static bool To(string url, object param = null, NavMode mode);

參數解釋:

  • string url:這個是必須的。我們把所有的頁面都指定了一個URL,淘搶購的主頁的URL定義如下:
public const string RushBuy_Home = "taobao://go/RushBuy/index"; 

 

  • object param:指定頁面間傳遞的參數。
  • NavMode mode:指定導航模式,是一個枚舉值,定義如下:
public enum NavMode
{ 
 Default, // show page in scenario frame
 Home_Add, // show page in scenario frame
 List_Add, // show page in list frame, keep old page (if exists) in back history
 List_Replace, // show page in list frame to replace the old page (clear old page in back history)
 Detail_Replace, // show page in detail frame to replace the old page (clear old page in back history)
 Detail_Replace_Clear, // same as above, also delete page in list frame
 Chat_Add, // show page in chat frame, keep old page (if exists) in back history
 Chat_Replace, // show page in chat frame to replace the old page (clear old page in back history)
 Chat_Replace_Clear, // same as above, also delete pages in list/detail frame
}

每個枚舉值都包含有兩個信息:位置,方式。如List_Add,下劃線前面的"List"表示位置,在List Frame中顯示目標頁面;下劃線後面的"Add"是方式,一共有三種方式:

  • Add:如果在目標Frame中已經有其它頁面存在,則在已有頁面基礎上再做一次Navigation,也就是back stack歷史中會多出一個記錄。
  • Replace:如果目標Frame中已有其它頁面存在,則"刪除"它,也就是在back stack中清空歷史記錄,然後做一次Navigation,最後back stack中只有最新的頁面記錄。
  • Replace_Clear:同Replace,另外,如果前面的Frame中(除了Home Frame以外),如果有頁面存在,則清除它們。

我們逐個解釋一下這些參數的用法。

為什麼需要Add/Replace方式?舉個例子,在淘寶首頁,假設用戶先點擊了天貓:

然後用戶又在左側首頁上點擊了淘搶購:

由於天貓和淘搶購都是在List Frame中顯示,於是淘搶購把天貓覆蓋了。此時用戶按Back鍵,希望看到什麼?顯然不是要回天貓!於是,我們是這樣指定淘搶購的導航方式的:

Nav.To(NavToUrls.RushBuy_Home, mode: NavMode.List_Replace); 

它指定了淘搶購在List Frame中顯示,用Replace方式,也就是清掉前面的天貓的痕跡。

何時用Add方式呢?比如用戶在首頁點了搜索:

右側進入了搜索起始頁面,用戶輸入搜索詞後按回車,再進入搜索結果頁面:

此時用戶想改一下搜索的關鍵字為lumia 950 xl,點擊一下搜索結果頁上方的搜索框,就會回到搜索起始頁。對於這個Scenario,我們需要這樣使用導航方法:

1)在首次進入搜索起始頁時,使用Replace方式來清空歷史:

Nav.To(NavToUrls.Go_Search, mode: NavMode.List_Replace); 

2)在進入搜索結果頁時,使用Add方式附加搜索結果頁:

Nav.To(NavToUrls.Search_Result, mode: NavMode.List_Add); 

如此一來,當用戶在搜索結果頁按返回鍵,或者點擊搜索框(等同於按返回鍵)時,就會在List Frame中調用Navigation Back方法,回到搜索起始頁,因為此時搜索起始頁一直在List Frame的歷史stack中等候。

何時使用Replace_Clear這種方式呢?對於有些Scenario,有一些特殊的導航需求,主要是為了保證左右兩側視窗的上下文關係。比如店鋪:

假設我們先看了店鋪簡介,現在左右兩側的視窗內容是有上下文關係的。此時,店鋪首頁在Home Frame中,店鋪簡介在List Frame中。我們用這個方法來顯示店鋪簡介頁:

Nav.To(NavToUrls.Shop_Brief, param: ViewModelData.ShopInfo?.ShopId, mode: NavMode.List_Replace); 

現在,左右兩側的情況是:Home Frame <-> List Frame。然後用戶在左側的店鋪首頁上點擊了一個商品,想看該商品的詳情,頁面就會變成這個樣子:

此時左右兩側的情況是:Home Frame <-> Detail Frame。那麼剛纔的用於顯示店鋪簡介的List Frame哪裡去了呢?被清掉了!因為我們使用了這個方式來顯示詳情頁:

Nav.To(data?.H5Url, mode: NavMode.Detail_Replace_Clear); 

請大家註意第二個參數,使用了Detail_Replace_Clear方式,表示在Detail Frame中顯示詳情頁,Replace該Frame中以前的內容,並且Clear掉List Frame中的所有頁面。於是,店鋪簡介頁面神奇地消失了,因為它不符合現在的上下文關係。當然,此時還需要其他一些手段來隱藏空白的List Frame,比如判斷List Frame的Content是否為空。

寫累了,喘口氣。剛纔在寫博客做截圖時,還發現了個Navigation的bug,順手給fix了,是調用參數寫錯了,應該寫成Detail_Replace_Clear,但是寫成了Detail_Replace,導致現線上上的版本,在店鋪頁,先點擊店鋪簡介,再在左側點擊全部寶貝,再點擊任意商品,此時,隨著視窗左滑,左側是店鋪簡介,右側是一個商品詳情,上下文關係不對。

本篇博客只是簡述了多視窗導航的原理和一些code片段,具體的實現可以根據個人應用場景的需求自己定製,尤其要註意多視窗之間的上下文關係。下次再說說頁面間通信和屏幕適配吧,Continuum其實也是一種屏幕適配。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • #列出所有被安裝的rpm package rpm -qa | grep mariadb #卸載 rpm -e mariadb-libs-5.5.37-1.el7_0.x86_64 錯誤:依賴檢測失敗: libmysqlclient.so.18()(64bit) 被 (已安裝) postfix-2:2 ...
  • <ignore_js_op> (點擊圖片瞭解詳情)Hi All:周四就可以放假了,開心不?無論是什麼節日,code4app都風雨無阻的為大家奉上weekly一封,並且提前祝大家端午節快樂,粽子你吃了嗎?<ignore_js_op> 又是一年一度的高考了,記得當年在考場上奮筆答題的你嗎?好啦好啦,我們 ...
  • 通過截圖記錄了使用vmware8新建虛擬機並安裝CentOS的過程 ...
  • # ifconfig 查看網卡信息,如下圖所示: # ifconfig eth0 192.168.0.107 eth0表示第一塊網卡,Linux中所有的設配都是文件,所以eth0是第一塊網卡的文件名, ip需要根據電腦的ip來配置,需要保證在同一個網段內才能通信,比如都在192.168.0這個網段 ...
  • Sublime Text是一款功能非常強大的輕量級代碼編輯器,有關功能介紹和使用可以看我另一篇文章的描述http://www.cnblogs.com/jaxu/p/5037547.html 不過,在Ubuntu系統上Sublime Text不支持輸入中文,如何解決呢? 搜索百度和Google,在gi ...
  • 又到周一工作日啦,為了給大家多打點雞血~code4app【iOS weekly】誕生了,從這周開始,每周一,為你推薦整理的上周code4app精華內容,需要的趕快mark下和關註,媽媽再也不用擔心我的學習了~ 【一周精品源碼】各種動畫的集合demo[img]file:///C:\Users\zhan ...
  • 2016-06-0711:05:44 在學習WCF時,學到WCF服務的同步和非同步。 我理解的同步是: 當WCF服務是同步執行時,程式只有一條線程,代碼只能按順序一步一步來執行,當執行客戶端/服務端某方法需要10秒時,只能等待10秒才能接著執行之後的代碼。 當WCF服務是非同步執行時,程式可以同時存在多 ...
  • 記得2010年之前,公司的項目基本上都要用到報表,以前我們常用的方法就是針對客戶的需求來定製化開發(基本上是死寫代碼)來實現,經常導致項目經常性的延期,因為客戶的需求經常會變化,隨著用戶的使用認知度的提高,對報表的要求越來越高,導致程式員不停的修改代碼來實現,效率不高、結束遙遙無期。。。非常的痛苦; ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...