模型
我创建了一个Movie
类用于保存关于电影的信息。同样的,我也创建了一个Actor
类用于保存演员的名字和头像url地址。这些仅仅是传入到我们的UI组件中,以便它们知晓要显示什么。
出于样例的目的,我创建一个文件,根据最初的设计,它保存了电影所需的所有模型。
models.dart
1 | class Movie { |
数据源
我们不打算将我们的应用程序与在线电影的API牵连在一起,使用其API本身就是另一个话题,这个超出了本文的范围。相反,我仅仅是创建了一个电影的实例,并填充了与模型相同的信息。
movie_api.dart
1 | import 'package:movie_details_ui/models.dart'; |
这个使我们能够在应用程序的任何地方来轻松使用地使用testMovie
作为数据源,同时还能提高我们的速度,无需担心网络问题。
我们的 main.dart 文件
这个是我们应用程序的主入口,这里没有特别的地方,仅仅是将MovieDetailsPage
作为该应用所拥有的唯一页面。
main.dart
1 | import 'package:flutter/material.dart'; |
在现实生活中,我们可能希望是将电影列表作为第一页显示,在用户点击一个电影后显示明细页面。在本教程,我们只关注电影明细页面。
MovieDetailsPage类
这个是我们电影明细页的入口,MovieDetailsPage
接收一个Movie
对象作为构造参数,并向下传给子组件。通过这种方式,随后我们可以轻松地将页面链接到一个后端。
movie_details_page.dart
1 | import 'package:flutter/material.dart'; |
尽管这个页面包含在一个脚手架中,但我们这里不使用AppBar,因为我们想要展示我们的电影背景。主体是一个Column
控件用来垂直地堆叠我们的主要的控件。最后,整个被包裹在SingleChildScrollView
控件中。对于垂直方向上的边距,我们使用SizedBoxes
配合height
属性来实现我们想要的间距。
让我们一个个浏览每个组件,看看他们是由什么构成的。
MovieDetailHeader 电影详情页面头部
这个MovieDetailHeader
是一个简单的Stack
控件,包含了两个子控件。Stack
是这样的一个容器,子控件能够相互在其上面堆叠地进行布局。第一个子控件是圆弧形背景图像,第二个是Row
控件,包含了海报以及电影的相关信息。
因为原模型设计是将电影横幅部分地覆盖在电影信息上,我们在这里使用了一个小技巧:ArcBannerImage
的底部填充间距140.0。
这只是延伸了底部可用的空间,因此我们可以部分地将横幅与电影信息覆盖起来。如果没有这个技巧,电影信息就会被放在整个横幅的顶部,从而产生一个相当丑陋的效果:
我们使用Positioned
控件来将我们的电影信息固定在底部。电影信息行包含了两项:电影海报和关于电影进一步的明细信息(这是一个Column
控件)。
movie_detail_header.dart
1 | import 'package:flutter/material.dart'; |
这个Column
控件包含了三个部分(子控件):电影标题,电影评分,电影分类。
有一点需要注意的是,我们这里使用了Expanded
控件,否则,如果电影名过长将会被剪切掉,此外还在左边添加了一些填充,这样海报和电影信息就不会紧紧挨着了。