flutter 第四天(上午--轮播图的实现 )
2019-05-31 本文已影响6人
雪纳瑞的哈士奇
今天继续写UI界面
今天的主要任务就是写轮播图
懒造就了程序员,能使用框架的坚决不自己写
轮播图的框架
(样式一)卖个关子先看效果
image实现方式
引入flutter_swiper库
flutter_swiper利用的是这个库,可以实现多样式的布局。先说说库的导入。 之前的文章有提到过本地图片的加载方式,是进入到pubspec.yaml文件里添加,同时,引入三方库也是一样。
找到这个地方,增加一行代码
flutter_swiper: ^1.0.6
然后到项目的目录下运行下面命令行 (这个过程可能会等一会,反正我是等了一会)
flutter packages get
等到提示完成的时候,那么这个库就导入完成了,下面看具体的实现。
具体代码实现
import 'package:flutter/material.dart';
import 'package:flutter_swiper/flutter_swiper.dart'; // 引入头文件
class SwiperView extends StatefulWidget {
@override
_SwiperViewState createState() => _SwiperViewState();
}
class _SwiperViewState extends State<SwiperView> {
// 声明一个list,存放image Widget
List<Widget> imageList = List();
@override
void initState() {
imageList
..add(Image.network(
'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2726034926,4129010873&fm=26&gp=0.jpg',
fit: BoxFit.fill,
))
..add(Image.network(
'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=3485348007,2192172119&fm=26&gp=0.jpg',
fit: BoxFit.fill,
))
..add(Image.network(
'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2594792439,969125047&fm=26&gp=0.jpg',
fit: BoxFit.fill,
))
..add(Image.network(
'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=190488632,3936347730&fm=26&gp=0.jpg',
fit: BoxFit.fill,
));
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black12,
appBar: AppBar(title: Text('轮播图'),),
body: ListView( // 这里使用listView是因为本地写了几组不同样式的展示,太懒了,所以这里就没有改
children: <Widget>[
firstSwiperView()
],
)
);
}
Widget firstSwiperView() {
return Container(
padding: const EdgeInsets.fromLTRB(0, 50, 0, 5),
width: MediaQuery.of(context).size.width,
height: 300,
child: Swiper(
itemCount: 4,
itemBuilder: _swiperBuilder,
pagination: SwiperPagination(
alignment: Alignment.bottomRight,
margin: const EdgeInsets.fromLTRB(0, 0, 20, 10),
builder: DotSwiperPaginationBuilder(
color: Colors.black54,
activeColor: Colors.white
)
),
controller: SwiperController(),
scrollDirection: Axis.horizontal,
autoplay: true,
onTap: (index) => print('点击了第$index'),
),
);
}
Widget _swiperBuilder(BuildContext context, int index) {
return (imageList[index]);
}
}
下面介绍一下几个常用的Swiper属性:
Swiper({
this.itemBuilder,
this.indicatorLayout: PageIndicatorLayout.NONE,
///
this.transformer,
@required this.itemCount, // 个数
this.autoplay: false, // 是否自动播放,默认false
this.layout: SwiperLayout.DEFAULT, // 设置样式,后面会介绍,default就是上面轮播的样式
this.autoplayDelay: kDefaultAutoplayDelayMs,
this.autoplayDisableOnInteraction: true, // 用户拖拽的时候,是否停止自动播放
this.duration: kDefaultAutoplayTransactionDuration, // 动画时间,默认300.0毫秒
this.onIndexChanged, // 当用户手动拖拽或自动播放引起下标改变的时候调用
this.index, // 初始播放轮播时的下标位置
this.onTap, // 点击轮播的事件
this.control, // 分页按钮(一般是左右或上下两边的箭头按钮)
this.loop: true, // 无限轮播模式开关
this.curve: Curves.ease, // 动画的方式
this.scrollDirection: Axis.horizontal, // 滚动方式
this.pagination, // 分页指示器(下面跟着滚动的点)
this.plugins,
this.physics,
Key key,
this.controller,
this.customLayoutOption,
/// since v1.0.0
this.containerHeight,
this.containerWidth,
this.viewportFraction: 1.0,
this.itemHeight,
this.itemWidth,
this.outer: false,
this.scale,
this.fade,
})
分页指示器pagination
分页指示器继承子SwiperPlugin,设置SwiperPagination()展示默认分页
const SwiperPagination(
{this.alignment, // 修改指示器的位置,默认bottomCenter(上面gif修改了这个属性)
this.key,
this.margin: const EdgeInsets.all(10.0), // 分页指示器与容器边框的距离(意味着可随意改变它的位置)
this.builder: SwiperPagination.dots}); // 默认的分页指示器的样式:SwiperPagination.dots(点形式)、SwiperPagination.fraction(分数形式),也可完全自定义哦
Widget build(BuildContext context, SwiperPluginConfig config) {
Alignment alignment = this.alignment ??
(config.scrollDirection == Axis.horizontal
? Alignment.bottomCenter
: Alignment.centerRight);
Widget child = Container(
margin: margin,
child: this.builder.build(context, config),
);
- SwiperPagination.dots(点形式)
pagination: SwiperPagination(
builder: DotSwiperPaginationBuilder(
color: Colors.white70, // 其他点的颜色
activeColor: Colors.redAccent, // 当前点的颜色
space: 2, // 点与点之间的距离
activeSize: 20 // 当前点的大小
)
)
image.png
-
SwiperPagination.fraction(分数形式)
image.png - 完全自定义
pagination:new SwiperCustomPagination(
builder:(BuildContext context, SwiperPluginConfig config){
return CustomPagination();
}
)
分页按钮control
分页按钮也是继承SwiperPlugin,设置SwiperControl()展示默认控制按钮。
const SwiperControl(
{this.iconPrevious: Icons.arrow_back_ios, // 上一个的Icons
this.iconNext: Icons.arrow_forward_ios, // 下一个的Icons
this.color, // 按钮颜色 (默认为主题色)
this.disableColor, // 禁用色(字面意思,说真的,我也不知道这货干嘛的😊)
this.key,
this.size: 30.0, // 控制按钮的大小,默认30.0
this.padding: const EdgeInsets.all(5.0)}); // 控制按钮与容器的距离(位置随意我们安排😂)
image
样式二
image实现代码
Swiper(
itemBuilder: (BuildContext context, int index) {
return Container( // 用Container实现图片圆角的效果
decoration: BoxDecoration(
image: DecorationImage(
image: secondImageList[index], // 图片数组
fit: BoxFit.cover,
),
borderRadius: BorderRadius.all(
Radius.circular(10.0),
),
),
);
}
)
样式三
image实现代码
Swiper(
itemCount: secondImageList.length,
itemBuilder: (BuildContext context, int index) {
return Container(
decoration: BoxDecoration(
image: DecorationImage(
image: secondImageList[index],
fit: BoxFit.fill
),
borderRadius: BorderRadius.all(
Radius.circular(10)
)
),
);
},
layout: SwiperLayout.STACK // stack样式
)
样式四
image实现代码
Swiper(
layout: SwiperLayout.CUSTOM, // custom样式
customLayoutOption: CustomLayoutOption(
startIndex: -1,
stateCount: 3
).addRotate([
-100.0/180,
0.0,
100.0/180
]).addTranslate([
Offset(-470.0, -40.0),
Offset(0.0, 0.0),
Offset(470.0, -40.0)
]),
itemWidth: 300,
itemHeight: 200,
itemBuilder: (context, index) {
return Container(
decoration: BoxDecoration(
image: DecorationImage(
image: secondImageList[index],
fit: BoxFit.fill
),
borderRadius: BorderRadius.all(
Radius.circular(10)
)
),
);
},
pagination: SwiperPagination(
builder: DotSwiperPaginationBuilder(
color: Colors.white,
activeColor: Colors.blue
)
),
itemCount: secondImageList.length,
autoplay: true,
autoplayDisableOnInteraction: true,
)
上面的文章一点一点复制于https://juejin.im/post/5c3f3c29f265da6120621048
感谢[佐笾]老铁
下面应该是我自己写的了把 不知道 再说吧
再说一个这个框架的不好的地方(不知道是否说错哈 如果有错误请大神指出来 和我一样的小白也不要把这个问题记住 因为很可能不是缺陷 毕竟如此完善的第三方库) 在使用滚动 图的时候必须要指定高度 不指定的话会有错误 这个是比较尴尬的一点
自定义控件
因为用到自定义控件 所以看了下人家的
https://www.jianshu.com/p/ca9b541b59e6
ListView 嵌套ListView
shrinkWrap: true, //解决无限高度问题
physics:NeverScrollableScrollPhysics(),//禁用滑动事件
要添加上上面的代码
可滑动控件都有这两个属性,给子滑动部件设置上这两个参数,即可办到子ListView跟随父ListView滑动。