四核驱动的三维导航—淘宝新UI(设计篇)
前面有一篇博客说到了淘宝UWP的"四核驱动的三维导航—淘宝新UI(需求分析篇)",花了两周的时间实现了这个框架,然后又陆陆续续用了三周的时间完善它。
多窗口导航,与传统的导航方式的最大的不同点是:
- 需要指定目标窗口(target Frame)
- 维护上下文关系(context)
- Back Stack的维护
- 页面间的异步通信
- 适配Desktop和Mobile界面
- 支持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其实也是一种屏幕适配。
四核驱动的三维导航—淘宝新UI(设计篇)的更多相关文章
- “四核”驱动的“三维”导航 -- 淘宝新UI(需求分析篇)
前言 孔子说:"软件是对客观世界的抽象". 首先声明,这里的"三维导航"和地图没一毛钱关系,"四核驱动"和硬件也没关系,而是为了复杂的应用而 ...
- 魅族MX四核手机转让,二手淘宝上+hi-pda论坛结合使用成功已出
2013-3-14 内容存档在evernote,笔记名"魅族MX四核手机转让,二手淘宝上+hi-pda论坛结合使用成功已出"
- YY淘宝商品数据库设计
http://www.cnblogs.com/mmmjiang13/archive/2010/11/04/1868609.html 前言 这几个月都在做一个通过淘宝API线下管理淘宝店的系统,学习了很 ...
- JAVA爬虫实践(实践四:webMagic和phantomjs和淘宝爬虫)
webMagic虽然方便,但是也有它不适用的地方,比如定向的某个单页面爬虫,或者存在大量ajax请求,页面的跳转请求全都混淆在js里. 这时可以用webMagic结合phantomjs来真实模拟页面请 ...
- 淘宝(新浪)API获取IP地址位置信息
package com.parse; import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.IO ...
- 基于Bootstrap仿淘宝分页控件实现
.header { cursor: pointer } p { margin: 3px 6px } th { background: lightblue; width: 20% } table { t ...
- 原生js仿淘宝手机购买选项代码
这是一款基于原生js实现仿淘宝手机信息购买选项效果源码,界面整体效果仿照淘宝购物选项设计,点击不同选项还可实时显示不同的价格计算结果,界面简洁大方.美观实用.可兼容目前最新的各类主流浏览器. 在线演示 ...
- Expression构建DataTable to Entity 映射委托 sqlserver 数据库里面金额类型为什么不建议用float,实例告诉你为什么不能。 sql server 多行数据合并成一列 C# 字符串大写转小写,小写转大写,数字保留,其他除外 从0开始用U盘制作启动盘装Windows10系统(联想R720笔记本)并永久激活方法 纯CSS打造淘宝导航菜单栏 C# Winform
Expression构建DataTable to Entity 映射委托 1 namespace Echofool.Utility.Common { 2 using System; 3 using ...
- 淘宝(阿里百川)手机客户端开发日记第十五篇 JSON解析(四)
解析一个从淘宝传递的JSON (大家如有兴趣可以测试下):{ "tae_item_detail_get_response": { "data": { " ...
随机推荐
- OSError: libcudart.so.7.5: cannot open shared object file: No such file or directory
在ubuntu14.04-64-bit,安装完cuda ,cudnn.opencv后, 配置完MXNet,运行demo 时出现错误,库路径环境变量问题,解决方法: sudo ldconfig /usr ...
- Delphi在创建和使用DLL的时候如果使用到string,请引入ShareMem单元
当使用了长字符串类型的参数.变量时,如string,要引用ShareMem. 虽然Delphi中的string功能很强大,但若是您编写的Dll文件要供其它编程语言调用时,最好使用PChar类型.如果您 ...
- NOIP主要考查范围
基本数据结构 栈 队列 数组 优先队列 中级数据结构 堆(大根堆,小根堆) 并查集和带权并查集 哈希表 高级数据结构 (可选学) 树状数组 线段树 各种其他树 字符串和相关内容 1.KMP 2.各种操 ...
- 数据库连接池c3p0学习
这里只记录c3p0的数据源,不会涉及到其它方面和别的数据库连接池的对比 配置文件主要的实现方式有三种: 1.手写代码去加载一个配置文件 创建一个config.properties文件如下: drive ...
- 让tomcat启动更快的设置
http://wiki.apache.org/tomcat/HowTo/FasterStartUp#Entropy_Source 关于随机数的"熵源"(entropy source ...
- iOS开发学习笔记
1 常用的第三方工具 1.1 iPhone Simulator 测试程序需要模拟器iPhone Simulator 1.2 设计界面需要Interface Builder,Interface Buil ...
- JS冒泡排序(div)
更生动的排序动画. 通过改变div的高度来实现排序,通过闭包来实现for循环的睡眠时间. <!doctype html> <html lang="en"> ...
- ue4 c++学习推荐
我由易到难推荐,不过在此之前还是先看看官方对于VS设置的推荐: https://docs.unrealengine.com/latest/INT/Programming/Development/Vis ...
- Code Complete 笔记—— 第一章
软件的构建的主要流程: 定义问题 ( Problem Definition) 需求分析 (Requirements Development) 规划构建 (construction planning) ...
- sublime插件
CnDict: 中英文字典软件,快捷键查词,目前支持金山词霸和有道词典. BracketHighlighter: 有个笑话,说前苏联间谍花了巨大的代价,偷到了阿波罗飞船的最后一屏的代码,发现全部是 } ...