好久没有自学flutter,有点落下,现在有空就抓紧补上,如标题所示,这篇博文是实现轮播图Swiper、GridView的组合布局及各自的点击事件,最后是将它们抽出方法来,而不是全部写在build里面,不然代码看起来不舒服而且不易维护。我自己摸索了一个上午,一边调试一边查阅资料,最后实现后,整理好代码就写这篇博文了。效果图如下所示(凑齐六宫格,重点后面一排):
说明:代码出现的自定义字体、使用本地图片,你可以不用它(图片换成网络的),如果你想用可是又不会用,可以看前面的flutter学习二(里面有涉及怎么使用本地图片)、flutter学习四(字体)。
一. 轮播图:
1. 在看代码之前,先添加swiper包,在pubspec.yaml里面添加如下图(按照提示依次操作):
2. 操作1后可以看如下代码了,关于用到的属性解释,我是根据自己的理解来备注的,网上有更多的属性及详细的说明,你可以网上查找,我这里就详细说了:
注:代码必须写在Widget build(BuildContext context)前面,getDialog( )是显示dialog的一个方法,后面会给出相关代码。
//本地图片,也可以使用网络图片
static List imageList = [
'images/lake.jpg',
'images/lake.jpg',
'images/lake.jpg'
];
Container(
//轮播图的高度
height: 120,
//轮播图,还有其它的属性,这里不一一介绍了
child: Swiper(
//有多少个
itemCount: imageList.length,
//是否自动滚动
autoplay: true,
//滚动的放心,左右、上下(默认左右)
scrollDirection: Axis.horizontal,
//用户滑动轮播图时是否停止自动播放
autoplayDisableOnInteraction: true,
itemBuilder: (BuildContext context, int index) {
return Image.asset(
//显示imageList里面的图片、imageList是网络图片时用Image.network
imageList[index],
fit: BoxFit.fill, //填充方式
);
},
//轮播改变时调用的(用户操作或者自动轮播)
onIndexChanged: (index) {
//相应的操作,一般也不操作
},
//点击某个轮播图
onTap: (index) {
showDialog(
context: context1,
barrierDismissible: true, //点击弹窗外部是否消失
child: getDialog("您点击了第:$index个轮播图"), //dialog显示点击的内容
);
},
//显示指示器,SwiperPagination()是默认,可以在里面修改位置、距离、样式
pagination: SwiperPagination(
alignment: Alignment.bottomCenter, //指示器的位置
margin: const EdgeInsets.only(bottom: 10), //瑜边框的距离
builder: SwiperPagination.dots, //指示器的样式:dots点、fraction数字
),
),
);
二. GridView的显示、点击事件及显示dialog:
注:代码必须写在Widget build(BuildContext context)前面
//显示的数据
static List chainList = ['武汉', '加油!', '中国', '加油!', '我们', '必胜!'];
Container(
child: GridView.count(
shrinkWrap: true,
//解决listView嵌套GridView不能滚动问题
physics: new NeverScrollableScrollPhysics(),
//水平之间的间距
crossAxisSpacing: 10.0,
//垂直之间的间距
mainAxisSpacing: 30.0,
//GridView内边距,all四个方向
padding: EdgeInsets.all(10.0),
//一行显示多少个Widget
crossAxisCount: 1,
//Widget宽高比例
childAspectRatio: 2.0,
//数据
children: getGridList(),
),
);
//获取GridView显示的数据,及设置子item的样式
static List<Widget> getGridList() {
return chainList.map((item) => getItemContainer(item)).toList();
}
//每个GridView里面的item设置
static Widget getItemContainer(String item) {
return new GestureDetector(
//点击事件 onTap轻按
onTap: () {
showDialog(
context: context1,
barrierDismissible: true, //点击弹窗外部是否消失
child: getDialog(item), //dialog显示点击的内容
);
},
child: new Container(
height: 80,
margin: EdgeInsets.only(bottom: 5),
alignment: Alignment.center,
decoration: BoxDecoration(color: Colors.red),
child: Text(
item,
style: TextStyle(color: Colors.white, fontSize: 20),
),
),
);
}
三. 在build里面将Swiper、GridView进行组合,更多的摸索的时间花在这里了,里面涉及到ListView嵌套GridView:
注:这样子组合,把对应分wigdet进行封装,而不是全部布局写在body: Center里面,是不是简洁好看多了,而且也方便管理
new ListView(
shrinkWrap: true,
children: <Widget>[
swiperSection,
gridSection,
],
),
四. 完整代码:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_swiper/flutter_swiper.dart';
class HomeScreen extends StatelessWidget {
//自定义字体
final textStyle = const TextStyle(
fontFamily: 'Chu',
color: Colors.red,
fontSize: 20,
);
//用于路由(就是界面的跳转),当跳转的事件没有写在build里面时用到(我这里抽到了loginButton里面)
static BuildContext context1;
//本地图片,也可以使用网络图片
static List imageList = [
'images/lake.jpg',
'images/lake.jpg',
'images/lake.jpg'
];
static List chainList = ['武汉', '加油!', '中国', '加油!', '我们', '必胜!'];
//轮播图控件,写在build的前面,Container创建矩形视觉元素,可对元素进行修饰eg:背景色、边框、边距、填充等
static Widget swiperSection = new Container(
//轮播图的高度
height: 120,
//轮播图,还有其它的属性,这里不一一介绍了
child: Swiper(
//有多少个
itemCount: imageList.length,
//是否自动滚动
autoplay: true,
//滚动的放心,左右、上下(默认左右)
scrollDirection: Axis.horizontal,
//用户滑动轮播图时是否停止自动播放
autoplayDisableOnInteraction: true,
itemBuilder: (BuildContext context, int index) {
return Image.asset(
//显示imageList里面的图片、imageList是网络图片时用Image.network
imageList[index],
fit: BoxFit.fill, //填充方式
);
},
//轮播改变时调用的(用户操作或者自动轮播)
onIndexChanged: (index) {
//相应的操作,一般也不操作
},
//点击某个轮播图
onTap: (index) {
showDialog(
context: context1,
barrierDismissible: true, //点击弹窗外部是否消失
child: getDialog("您点击了第:$index个轮播图"), //dialog显示点击的内容
);
},
//显示指示器,SwiperPagination()是默认,可以在里面修改位置、距离、样式
pagination: SwiperPagination(
alignment: Alignment.bottomCenter, //指示器的位置
margin: const EdgeInsets.only(bottom: 10), //瑜边框的距离
builder: SwiperPagination.dots, //指示器的样式:dots点、fraction数字
),
),
);
//GridView控件
static Widget gridSection = new Container(
child: GridView.count(
shrinkWrap: true,
//解决listView嵌套GridView不能滚动问题
physics: new NeverScrollableScrollPhysics(),
//水平之间的间距
crossAxisSpacing: 10.0,
//垂直之间的间距
mainAxisSpacing: 30.0,
//GridView内边距,all四个方向
padding: EdgeInsets.all(10.0),
//一行显示多少个Widget
crossAxisCount: 1,
//Widget宽高比例
childAspectRatio: 2.0,
//数据
children: getGridList(),
),
);
//获取GridView显示的数据,及设置子item的样式
static List<Widget> getGridList() {
return chainList.map((item) => getItemContainer(item)).toList();
}
//每个GridView里面的item设置
static Widget getItemContainer(String item) {
return new GestureDetector(
//点击事件 onTap轻按
onTap: () {
showDialog(
context: context1,
barrierDismissible: true, //点击弹窗外部是否消失
child: getDialog(item), //dialog显示点击的内容
);
},
child: new Container(
height: 80,
margin: EdgeInsets.only(bottom: 5),
alignment: Alignment.center,
decoration: BoxDecoration(color: Colors.red),
child: Text(
item,
style: TextStyle(color: Colors.white, fontSize: 20),
),
),
);
}
//显示点击事件
static Widget getDialog(String item) {
return new AlertDialog(
title: new Text(
//标题
'提示',
style: new TextStyle(color: Colors.red[300], fontSize: 18),
),
content: new Text(item), //提示语
actions: <Widget>[
new FlatButton(
//一个扁平的Material按钮
onPressed: () {
Navigator.of(context1).pop(); //弹窗消失
},
child: Text('取消')),
new FlatButton(
//对话框按钮
onPressed: () {
Navigator.of(context1).pop(); //弹窗消失
},
child: Text('确定')),
],
);
}
Widget build(BuildContext context) {
context1 = context;
return new Scaffold(
appBar: new AppBar(
title: new Text(
'首页',
style: textStyle,
),
),
body: new ListView(
shrinkWrap: true,
children: <Widget>[
swiperSection,
gridSection,//涉及listView嵌套GridView
],
),
);
}
}
到此完成了,有更好的建议评论区见!