跟我学ASP.NET MVC之八:SportsStrore移动设备
摘要:
现在的web程序开发避免不了智能手机和平板电脑上的使用,如果你希望发布你的应用程序给更广大客户使用的话,你将要拥抱可移动web浏览器的世界。向移动设备用户发布一个好的使用体验是很困难的-比只是发布桌面内容要难得多。它需要认真的计划,设计以及大量的测试。甚至很容易被新的移动设备或平板电脑困住。
MVC框架确实有一些特征帮助移动开发。但是MVC框架是一个服务端框架,接收HTTP请求并发出HTTP响应。你在开发移动客户端的时候,会碰到很多的困难,而它对这些的作用却很受限。MVC框架使用不同的移动设备策略,可以帮助到不同层面。有三个基本的你可以使用的移动设备策略,下面将分别介绍它们。
什么都不做(尽量少地做)
看起来像一个奇怪的主意,但是一些移动设备是能够处理那些为桌面客户端开发的内容的。许多的移动设备-不得不承认当今最新的-有高屏幕分辨率,很大的内存,可以快速地呈现HTML以及运行JavaScript。
响应式设计
另一个策略是为适应支持它将显示的设备,而创建页面内容。被称为响应式设计。CSS标准有能力让你根据设备的性能改变应用在元素上的样式,它是一个经常被使用的根据屏幕尺寸改变内容的排版的技术。
响应式设计是使用CSS处理的东西,它不直接由MVC框架管理。这篇文章将介绍如何使用Bootstrap库里包含的响应式设计,来装饰SportsStore应用程序。
创建响应式设计的页面头部
修改_Layout.cshtml文件。
1 <!DOCTYPE html> 2 3 <html> 4 <head> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <link href="~/Content/bootstrap.css" rel="stylesheet" /> 7 <link href="~/Content/bootstrap-theme.css" rel="stylesheet" /> 8 <link href="~/Content/ErrorStyles.css" rel="stylesheet" /> 9 <title>@ViewBag.Title</title> 10 <style> 11 .navbar-right { 12 float: right !important; 13 margin-right: 15px; 14 margin-left: 15px; 15 } 16 </style> 17 </head> 18 <body> 19 <div class="navbar navbar-inverse" role="navigation"> 20 <a class="navbar-brand" href="#"> 21 <span class="hidden-xs">SPORTS STORE</span> 22 <div class="visible-xs">SPORTS</div> 23 <div class="visible-xs">STORE</div> 24 </a> 25 @Html.Action("Summary", "Cart") 26 </div> 27 <div class="row panel"> 28 <div id="categories" class="col-xs-3"> 29 @Html.Action("Menu", "Nav") 30 </div> 31 <div class="col-xs-8"> 32 @RenderBody() 33 </div> 34 </div> 35 </body> 36 </html>
我将显示SPORTS STORE品牌的链接,改成了现在这个样子。
<a class="navbar-brand" href="#">SPORTS STORE</a>
BootStrap使用一种称为media查询的方式定义了一系列的样式,hidden-xx和visible-xx。xx可以使用xs、sm、md、lg代替,分别表示超小屏幕、小屏幕、中等屏幕和大屏幕。
.col-xs- 超小屏幕 手机 (<768px)
.col-sm- 小屏幕 平板 (≥768px)
.col-md- 中等屏幕 桌面显示器 (≥992px)
.col-lg- 大屏幕 大桌面显示器 (≥1200px)
这里使用的是hidden-xs和visible-xs。
hidden-xs:在超小屏幕上隐藏该元素。
visible-xs:在超小屏幕上显示该元素。
运行程序,在大屏幕尺寸上,页面内容没有变化。如果将浏览器缩小到小于768px,SPORTS STORE链接文字将变成两行。
创建响应式布局的购物车摘要
修改Summary.cshtml文件。
1 @model SportsStore.Domain.Entities.Cart 2 3 <div class="navbar-right hidden-xs"> 4 @Html.ActionLink("My Cart", "Index", "Cart", new { returnUrl = Request.Url.PathAndQuery }, new { @class = "btn btn-default navbar-btn" }) 5 </div> 6 <div class="navbar-right visible-xs"> 7 <a href=@Url.Action("Index", "Cart", new { returnUrl = Request.Url.PathAndQuery }) class="btn btn-default navbar-btn"> 8 <span class="glyphicon glyphicon-shopping-cart"></span> 9 </a> 10 </div> 11 <div class="navbar-text navbar-right"> 12 <b class="hidden-xs">Your cart:</b> 13 @Model.CartLines.Sum(x => x.Quantity) item(s), 14 @Model.ComputeTotalValue().ToString("c") 15 </div>
首先,在不希望在手机屏幕上(<768px)显示的页面元素,添加hidden-xs样式。这样,这两个元素在手机屏幕上将不会显示。
<div class="navbar-right hidden-xs"> @Html.ActionLink("My Cart", "Index", "Cart", new { returnUrl = Request.Url.PathAndQuery }, new { @class = "btn btn-default navbar-btn" }) </div> <b class="hidden-xs">Your cart:</b>
然后,为手机屏幕显示的导航到购物车明细超链接,定义自己的样式。
<div class="navbar-right visible-xs"> <a href=@Url.Action("Index", "Cart", new { returnUrl = Request.Url.PathAndQuery }) class="btn btn-default navbar-btn"> <span class="glyphicon glyphicon-shopping-cart"></span> </a> </div>
这里直接写<a></a>元素。因为需要使用<span></span>元素定义超链接文字样式。
class=”glyphicon glyphicon-shopping-cart”是定义在BootStrap里的文字样式,它将显示一个小的购物车图标。
运行程序,在大屏幕尺寸上,页面内容没有变化。如果将浏览器缩小到小于768px,购物车摘要将显示成下面截图那样的购物车图标。
创建响应式布局的产品列表
在超小屏幕上,左边的导航菜单占用宽度有点大。我希望在超小屏幕上隐藏左边的导航菜单,而是将导航菜单做成按钮组显示在页面头部。
继续修改_Layout.cshtml文件。
1 <!DOCTYPE html> 2 3 <html> 4 <head> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <link href="~/Content/bootstrap.css" rel="stylesheet" /> 7 <link href="~/Content/bootstrap-theme.css" rel="stylesheet" /> 8 <link href="~/Content/ErrorStyles.css" rel="stylesheet" /> 9 <title>@ViewBag.Title</title> 10 <style> 11 .navbar-right { 12 float: right !important; 13 margin-right: 15px; 14 margin-left: 15px; 15 } 16 </style> 17 </head> 18 <body> 19 <div class="navbar navbar-inverse" role="navigation"> 20 <a class="navbar-brand" href="#"> 21 <span class="hidden-xs">SPORTS STORE</span> 22 <div class="visible-xs">SPORTS</div> 23 <div class="visible-xs">STORE</div> 24 </a> 25 @Html.Action("Summary", "Cart") 26 </div> 27 <div class="visible-xs"> 28 @Html.Action("Menu", "Nav", new { horizontalLayout = true }) 29 </div> 30 <div class="row panel"> 31 <div id="categories" class="col-sm-4 hidden-xs"> 32 @Html.Action("Menu", "Nav") 33 </div> 34 <div class="col-sm-8 col-xs-12"> 35 @RenderBody() 36 </div> 37 </div> 38 </body> 39 </html>
- 首先,修改左边导航菜单所在的DIV元素样式,添加hidden-xs,指定它再超小屏幕上不显示。修改右边产品列表所在的DIV元素样式,添加col-xs-12,指定在超小屏幕,宽度上占全部12列显示。
- 然后,重新修改在小屏幕以及以上屏幕上,这两个DIV所占的宽度。col-sm-4指定左边菜单导航栏占三列。col-sn-8指定右边产品列表占8列。
- 最后,使用visible-xs重新定义在超小屏幕上的产品导航栏。它仍旧以DIV显示,但是他的位置在页面头部,所以讲他写到class=”row”所在的DIV上面。
- 向Html.Action方法传入第三个参数,它是一个动态类型对象,定义了一个自定义属性horizontalLayout。将修改Menu视图,在Menu视图上能够获得传入视图的动态类型对象的动态属性值,根据属性值显示不同样式的菜单。
修改Menu.cshtml文件,根据传入的动态属性值,显示不同的菜单样式
1 @model IEnumerable<string> 2 3 @{ 4 var horizontalLayout = (bool)(ViewContext.RouteData.Values["horizontalLayout"] ?? false); 5 var wrapperClass = horizontalLayout ? "btn-group btn-group-justified btn-group-md" : null; 6 } 7 8 <div class=@wrapperClass > 9 @Html.RouteLink("Home", new { controller = "Product", action = "List" }, new { @class = horizontalLayout ? "btn btn-default btn-sm" : "btn btn-block btn-default btn-lg" }) 10 @foreach (var link in Model) 11 { 12 @Html.RouteLink(link, new 13 { 14 controller = "Product", 15 action = "List", 16 category = link, 17 page = 1 18 }, new 19 { 20 @class = (horizontalLayout ? "btn btn-default btn-sm" : ("btn btn-block btn-default btn-lg")) + (link == ViewBag.SelectedCategory ? " btn-primary" : "") 21 }) 22 } 23 </div>
- 通过ViewContext对象,获得传入到视图的动态类型对象ViewContext.RoutData,再通过ViewContext.RoutData.Values这个Dictionary,获得动态类型对象的动态属性值。
- wrapperClass定义了超小屏幕上的按钮组样式。如果是超小屏幕,则按新的样式显示。否则它的值为null,MVC系统将在页面上自动删除这个class属性(将只显示成<div>)。
- 超小屏幕的按钮组样式定义:btn-group btn-group-justified btn-group-sm,定义它是一个按钮组,自动对齐方式以及按钮组每个按钮尺寸。
- 因为超小屏幕上显示成按钮组,而不是每个按钮单独一行btn-block的按钮,所有需要重新修改每个按钮的样式。使用条件表达式 horizontal?: 重新定义分组按钮样式为:btn btn-default btn-sm。与中等屏幕上的按钮不同的地方是尺寸,以及删除了btn-block。
运行程序,在大屏幕尺寸上,页面内容没有变化。如果将浏览器缩小到小于768px,导航菜单将变成下面截图的页面这样。