夫君子之行,静以修身,俭以养德,非淡泊无以明志,非宁静无以致远。——诸葛亮
安卓个大市场和苹果商店里面的应用,很多功能效果都有相似之处.应用没有创新可言了,都是在借鉴.例如:欢迎页倒计时、广告、首页顶部导航或者顶部导航、首页滚动banner等等.貌似这些功能的出现已经是理所当然了.最近产品经理需要我们实现一个顶部自动滚动的banner,每张banner内容都是圆角.如果用原生来做还是比较容易实现的并且很好的完成了适配.如果用Flutter来实现呢? 这时我们需要撇开用什么技术实现的,可以探讨一下如何达到我们想要的效果,而且成功的完成适配.
banner默认情况:
banner加载完成:
使用依赖库:
flutter_swiper : ^1.1.6
https://pub.flutter-io.cn/packages/flutter_swiper
loop | 是否循环 bool |
duration | 循环周期 毫秒 |
autoplay | 是否自动播放 bool |
scrollDirection | 滚动方向 上下或者水平 |
itemCount | banner数量 |
viewportFraction | banner占用父容器或者父视图宽度比例 |
scale | <1.0 和 viewportFactiton一起使用 |
itemBuilder | banner每一项视图(图片或者文本) |
............................................................................................................................. |
@override
Widget build(BuildContext _buildContext) {
int banLen = _banner.length;
double width = ViewUtils.getScreenWidth(_buildContext);
double curWidth = width * 0.92;
double curHeight = curWidth * 187 / 670;
return (banLen > 0)
? Container(
margin: EdgeInsets.only(top: ViewUtils.currentHeight(38.0)),
width: width,
height: curHeight,
child: Column(
children: <Widget>[
Expanded(
flex: 1,
child: Swiper(
containerHeight: ViewUtils.currentHeight(100.0),
controller: SwiperController(),
itemBuilder: (BuildContext context, int index) {
return _itemBuilder(index,curWidth,curHeight);
},
loop: true,
duration: 300,
autoplay: true,
scrollDirection: Axis.horizontal,
itemCount: banLen,
viewportFraction: 0.92,
// 当前视窗展示比例 小于1可见上一个和下一个视窗
scale: 0.96, // 两张图片之间的间隔
),
),
],
),
)
: Container();
}
思路:
1、获取要加载的图片的宽与高的比例
2、计算banner实际宽度
A:如果banner填充屏幕宽,那么banner就是屏幕宽度
B:如果banner距离屏幕左右有距离,那么banner宽度=屏幕宽度-两边距离的和.
3、根据屏幕的宽度计算banner父容器或父视图高度(网络图片高/网络图片宽*banner宽)
4、设置圆角
获取要加载图片的宽与高的比例(直接查看或者通过代码动态获取)
下载网络图片并查看图片的详细信息并计算图片的比例
通过代码获取,可参考:
Flutter获取图片大小(网络图片和本地图片)https://www.jianshu.com/p/ee62849752e8
计算banner实际宽度
若banner填充屏幕:
MediaQuery.of(_buildContext).size.width
若banner存在边距离:
MediaQuery.of(_buildContext).size.width * viewportFraction(<1.0)
根据屏幕的宽度计算banner父容器或父视图高度(网络图片高/网络图片宽*banner宽)
若banner填充屏幕:
MediaQuery.of(_buildContext).size.width * 187 /670
若banner存在边距离:
MediaQuery.of(_buildContext).size.width * viewportFraction(<1.0) * 187 /670
最后设置圆角
_itemBuilder(_index,_curWidth,_curHeight ){
String imgUrl = _banner[_index].imgUrl;
return GestureDetector(
onTap: () {
},
child: Container(
width: _curWidth,
height: _curHeight,
decoration: BoxDecoration(
gradient: const LinearGradient(
colors: [Color(0xFF819FF5), Color(0xFF4A66E7)]),
borderRadius: BorderRadius.all(
Radius.circular(10),
),
image: DecorationImage(
image: NetworkImage(imgUrl),
fit: BoxFit.fitWidth,
)),
),
);
}
总结:
不管是原生开发,还是用混合开发.为了屏幕适配,我们有时都需要动态计算屏幕都宽高,达到屏幕适配.
参考:
flutter_swiper : https://pub.flutter-io.cn/packages/flutter_swiper#-readme-tab-
BoxDecoration : https://book.flutterchina.club/chapter2/flutter_assets_mgr.html?h=BoxDecoration
NetworkImage : https://book.flutterchina.club/chapter3/img_and_icon.html?h=NetworkImage