您好,欢迎关注我的专栏,本文章是关于 Flutter 的系列文,从简单的 Flutter 介绍开始,一步步带你了解进入 Flutter 的世界。你最好有一定的移动开发经验,如果没有也不要担心,在我的专栏底部给我留言,我会尽我的能力给你解答。
上篇文章我们从主题、提示、图片加载和动画四个方向介绍了Flutter的UI基础,本篇专栏用一个PageView的实例来加深印象,并且在之后的专栏里,我们会深化这个示例,做成一个支持上下左右无限滑动的图片Banner,并且教你如何把他做成Dart library并且开放给其他人使用。
一.无限滑动的PageView
在实现PageView指示器之前,咱们需要先实现一个PageView。在Flutter中实现一个PageView很简单。
class BannerGalleryWidget extends StatefulWidget {
@override
State createState() {
return BannerGalleryWidgetState();
}
}
class BannerGalleryWidgetState extends State {
final PageController controller = PageController(initialPage: 200);
@override
Widget build(BuildContext context) {
return SizedBox(
height: 250.0,
child: Container(
color: Colors.grey,
child: PageView.builder(
controller: controller,
itemBuilder: (context, index) {
return new Center(
child: new Text('页面 ${index}'),
);
},
),
));
}
}
以上代码会得出这样一个界面。稍微解释一下代码:
/// 指定一个控制器,用来控制PageView的滑动,以及初始位置在第200页
/// 主要为了实现“无限循环”
final PageController controller = PageController(initialPage: 200);
/// 一个固定大小的容器,这里指定了他的高为250
SizedBox(height: 250.0)
/// 一个容器,用来设定背景颜色为灰色
Container(color: Colors.grey)
/// 主角PageView,文字居中显示当前的索引。
PageView.builder(
controller: controller,
itemBuilder: (context, index) {
return new Center(
child: new Text('页面 ${index}'),
);},),
二.实现一个指示器
有了无限滑动的PageView之后,咱们再来关联一个指示器:
class Indicator extends StatelessWidget {
Indicator({
this.controller,
this.itemCount: 0,
}) : assert(controller != null);
/// PageView的控制器
final PageController controller;
/// 指示器的个数
final int itemCount;
/// 普通的颜色
final Color normalColor = Colors.blue;
/// 选中的颜色
final Color selectedColor = Colors.red;
/// 点的大小
final double size = 8.0;
/// 点的间距
final double spacing = 4.0;
/// 点的Widget
Widget _buildIndicator(
int index, int pageCount, double dotSize, double spacing) {
// 是否是当前页面被选中
bool isCurrentPageSelected = index ==
(controller.page != null ? controller.page.round() % pageCount : 0);
return new Container(
height: size,
width: size + (2 * spacing),
child: new Center(
child: new Material(
color: isCurrentPageSelected ? selectedColor : normalColor,
type: MaterialType.circle,
child: new Container(
width: dotSize,
height: dotSize,
),
),
),
);
}
@override
Widget build(BuildContext context) {
return new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: new List.generate(itemCount, (int index) {
return _buildIndicator(index, itemCount, size, spacing);
}),
);
}
}
这段代码比较简单,在build()方法里面构建了一个横向的List。
List的Item是一个固定大小的圆点,选中是一种颜色,没有选中是另一种颜色。
三.关联PageView和指示器
class BannerGalleryWidgetState2 extends State {
final PageController controller = PageController(initialPage: 200);
void _pageChanged(int index) {
setState(() {});
}
@override
Widget build(BuildContext context) {
return Column(
children: [
SizedBox(
height: 150.0,
child: Container(
color: Colors.grey,
child: PageView.builder(
onPageChanged: _pageChanged,
controller: controller,
itemBuilder: (context, index) {
return new Center(
child: new Text('页面 ${index}'),
);
},
),
)),
Indicator(
controller: controller,
itemCount: 5,
),
],
);
}
}
把布局容器改一下,用一个列包裹PageView和Indicator,给PageView加一个onPageChanged,检查当页面修改的时候setState()刷新UI就好了。
四.总结
至此,无限滑动的PageView指示器已经完成了,虽然看起来和专栏一开始的示例图片有点小小的差别,但是至少需求实现了。但是现在这个指示器还比较傻,比如选中之后才会变色,而且不会放大显示。在之后的专栏里我教大家如何完善这个指示器以及提供整个工程的完整代码,敬请期待。
通过这篇文章,大家学会了如何实现一个PageView的指示器。下一篇专栏我会教大家如何使用Flutter请求Restful API,Json解析,手势处理以及页面跳转。