第三课:布局
我发现制作一个应用最好从基础布局开始 — 他基本可以看作是线图联系,帮助固化应用的需求。我们这个应用的布局没啥特别的东西,但是有一个需要添加的用户界面元素需要一点点技巧。
我们这个应用有两个页面,主页和滑页,本课中将会制作他们的模板。滑页非常简单,所以本课的大部分都是关于主页的。
Home页
主页有一个用户拍的照片的列表,用户可以在其中删除它们,一个拍新的照片的选项(只有在当日没拍的情况下),一个展示图片滑页的选项。效果图上这样的:
这个布局最有技巧性的是顶部的“SMILE!”图片,实际上是一个按钮,用于拍照的按钮,同时,他也只会在用户当日没有拍照的情况下才显示。如果用户当日没有拍照的话就不会显示的。
我们先从基础布局入手,然后看怎么实现拍照按钮。
> 修改src/pages/home/home.html 为如下:
<ion-header>
<ion-navbar color="danger">
<ion-title>
<img src="assets/images/logo.png" />
</ion-title>
<ion-buttons end>
<button ion-button icon-only (click)="playSlideshow()"><ion-icon name="play"></ion-icon></button>
</ion-buttons>
</ion-navbar>
</ion-header>
<ion-content>
<ion-list>
<ion-item-sliding>
<ion-item>
<img src="http://placehold.it/100x100" />
<ion-badge item-right light>0 days ago</ion-badge>
</ion-item>
<ion-item-options>
<button ion-button icon-only light (click)="removePhoto(photo)"><ion-icon name="trash"></ion-icon></button>
</ion-item-options>
</ion-item-sliding>
</ion-list>
</ion-content>
我们把这个模板打碎来讲解。模板的第一个部分是导航条:
<ion-navbar color="danger">
<ion-title>
<img src="assets/images/logo.png" />
</ion-title>
<ion-buttons end>
<button ion-button icon-only (click)="playSlideshow()"><ion-icon name="play"></ion-icon></button>
</ion-buttons>
</ion-navbar>
ion-navbar 允许我们添加一个页首条到我们的应用顶部用于持有按钮,标题,甚至在需要的时候直接整合Ionic导航系统来展示一个回退按钮。
我们给navbar添加了danger属性将他样式化到我们的danger颜色,这个颜色变了色在variables.scss中定义的(后续会配置)。
在navbar中我们用到了ion-title,基本就是用来展示当前页面的文本标题和logo的。同时我们也用到了ion-buttons来创建按钮。通过指定end属性,所有按钮将被排列在右边,当我们指定的是‘start’属性的时候,将会从左边开始排列。
最后,我们将所有按钮列入ion-buttons中。这个按钮用到了一个play图标,有一个点击处理器,处理器将调用home.ts文件里的playSlideshow()函数(这个函数当前未创建)。
模板接下来的部分是内容部分,包括了一个列表:
<ion-content>
<ion-list>
<ion-item-sliding>
<ion-item>
<img src="http://placehold.it/100x100" />
<ion-badge item-right light>0 days ago</ion-badge>
</ion-item>
<ion-item-options>
<button ion-button icon-only color="light" (click)="removePhoto(photo)"><ion-icon name="trash"></ion-icon></button>
</ion-item-options>
</ion-item-sliding>
</ion-list>
</ion-content>
在看列表之前,我们看到所有东西都被包围在ion-content里 — 这就是页面主体内容展示的地方,在大部分情况下除了导航条外的所有内容都要放在这里。
跟一个普通列表其实也差不多,看:
<ul>
<li></li>
<li></li>
<li></li>
</ul>
Ionic里面创建列表的方式基本一样:
<ion-list>
<ion-item></ion-item>
<ion-item></ion-item>
<ion-item></ion-item>
</ion-list>
当然,我们的看起来稍微复杂点,所以我们还是来研究研究。首先与常理不一样的是我们在ion-list加入了no-lines属性。就像给navbar添加的danger属性一样,这个属性会对我们的列表起作用,他会使列表项不显示边缘。
接下来的变得多一点技巧性,也就是我们设置滑动项的地方。一个
第一部分
最后,我们来到了代码的第二部分,
现在,我们来添加之前讲到的那个条件照片按钮。
> 修改 src/pages/home/home.html 的 content 部分为如下:
<ion-content>
<ion-list>
<button ion-item *ngIf="!photoTaken" detail-none (click)="takePhoto()">
<img src="assets/images/smile.png" />
</button>
<ion-item-sliding>
<ion-item>
<img src="http://placehold.it/100x100" />
<ion-badge item-right light>0 days ago</ion-badge>
</ion-item>
<ion-item-options>
<button ion-button icon-only color="light" (click)="removePhoto(photo)"><ion-icon name="trash"></ion-icon></button>
</ion-item-options>
</ion-item-sliding>
</ion-list>
</ion-content>
注意,我们在列表里的滑动选项上面加入了一个新的项,但是我们不是直接用的
由于按钮会默认有自带样式的,而我们这里不想要那些样式,所以我们给他添加了detail-none属性。当然,我们也给他添加了一个点击处理器用于触发后面将会创建的takePhoto函数,但是这里最重要的还是 ngIf 指令。
ngIf 是Angular2提供的条件指令之一,允许我们根据数据改变模板显示。在现在的模板中,含有 ngIf 指令的元素只会在表达式为true的时候才会全部显示。由于我们的表达式是这样的:
*ngIf="!photoTaken"
所以我们的按钮只有在photoTaken为false的时候才会显示。稍后,我们会在home.ts中创建一个photoTaken变量用于追踪用户当日是否拍照。
现在运行以下命令的话:
ionic serve
会看到如下效果图:
显然,还有很多事情需要去完成,但是目前我们只需要对主页做这么多就够了,所以,我们继续Slideshow 页。
Slideshow 页
就像我之前说过的那样,slideshow页将会超级简单。他就是一个弹出的模态框展示所有用户拍的照片的滑页。我们只需要为照片提供一个容器,一个按钮来重启滑页和一个按钮来关闭页面就可以了。
> 修改 src/pages/slideshow/slideshow.html 为如下:
<ion-header>
<ion-toolbar color="danger">
<ion-title>Play</ion-title>
<ion-buttons start>
<button ion-button icon-only (click)="playPhotos()"><ion-icon name="refresh"></ion-icon></button>
</ion-buttons>
<ion-buttons end>
<button ion-button icon-only (click)="closeModal()"><ion-icon name="close"></ion-icon></button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content>
<div class="image-container">
<img #imagePlayer id="imagePlayer" src = "" />
</div>
</ion-content>
你已经知道navbar和按钮咋工作的了,所以唯一的新玩意是图片播放器(image player)。我们只是在内容显示区域添加了一个图片元素。稍后,我们会添加一些代码循环所有用户的照片,通过改变src属性来展示所有照片。我们只要在类里面拿到img的引用就可以了,所以我们创建了一个局部变量 #imagePlayer 这样可以直接在类定义中拿到他了。
目前而言,以上就是我们本课的工作量 — 告诉过你很简单的。
总结
现在,我们应用的两个页面都设置好了,下节课将会进行一些更有趣的事情。实际上,他可能是最有趣的课程之一,因为我们要学习整合本机Camera API然后用他来拍照。