Flutter制作图片横幅轮播
制作店面应用时,需要用到轮播。我看到flutter的控件库中没有这样的控件(当然,也许我只是错过了),所以我决定自己做一个banner轮播。该照片已发布。
框架
- 整体框架是PageView,一个指示器和一个计时器。
- PageView 用于显示需要播放的小部件。它不必仅限于显示图像。
- 指示器用作当前图像的指示器,需要指示Page关注当前。并且指示器应该能够设置半径、选定的颜色和未选定的颜色。最后,你可以设置标志的位置,左上,右下。
- 定时器,当节目需要定时播放时,就会按照设定的时间间隔播放对应的widget。这里需要注意的是,当你按下手的时候,需要取消时间限制,当你松开点击的时候,需要重新设置时间限制。当接口被销毁时,定时器也被销毁。
- Page点击了一下,又显示来电了。点击播放Page时需要以适当的方式回调。
应用
1. PageView
的实现如上代码:
_controller = PageController(initialPage: ,);Widget pageView = GestureDetector(onHorizontalDragDown: _onTaped,onTap: _onPageClicked,child: PageView(children: widget.childWidget,scrollDirection: widget.scrollDirection,onPageChanged: onPageChanged,controller: _controller,),);
Page Controller是一个Page控制器。可以设置Page的首次显示,也可以设置多张图片滚动时释放页面。您可以通过滚动来设置部分显示区域。可以外部调用initialPage,默认设置为0。
2。实现指针
上面的代码:
Widget indicatorWidget = Row(mainAxisAlignment: MainAxisAlignment.center,mainAxisSize: MainAxisSize.max,crossAxisAlignment: CrossAxisAlignment.center,children: widget.childWidget.map((f) {int index = (f);Widget indicatorWidget = Container(width: ().width,height: ().height,margin: (right: ),decoration: new BoxDecoration(shape: BoxShape.circle,color: index == selectedPage? widget.indicatorSelectedColor: widget.indicatorColor,),);return indicatorWidget;},).toList(),);
当多个widget需要旋转时,默认指针按数字排序并显示在中间。唯一的子索引是一个圆,颜色和半径可以外部设置。所选Page的标志应为所选颜色,其他指标应为非所选颜色。 ? ,否则需要使用 Stack 来堆叠这两个 widget。PageView在底部,标志在顶部。如今,它的位置也可以从外部设置。指针的位置可以通过Align来确定,通常是在bottom之上,所以这里给Positioned的bottom参数设置一个值。当然,我们也可以为这个位置以及距该位置的距离提供一个外部接口。
这里最后要做的是设置这个stackWidget的文本方向,因为在某些国家文本阅读方向是从右到左。如果您现在不安装,将会显示错误。我这里是从左到右写的。 :
Widget parent = Directionality(textDirection: TextDirection.ltr,child: Container(width: widget.width, height: widget.height, child: stackWidget));
当然,Android提供了试用方法:
Configuration config = getResources().getConfiguration();if(() == ) {//in Right To Left layout}
现在widget级别就结束了。
4。计时器
连续启动。该方法是flutter提供的:
void _startTimer() {if ( <= 0) {return;}var oneSec = Duration(seconds: );_timer = new Timer.periodic(oneSec, (Timer timer) {++selectedPage;selectedPage = selectedPage % widget.childWidget.length;_controller?.jumpToPage(selectedPage);onPageChanged(selectedPage);});}
autoDisplayInterval 外部设置时间间隔。如果不设置,默认情况下不会自动播放。如果设置为大于0的数字,则会自动播放。时间间隔为秒。另外,每次激活时,选择播放的页数都会增加1,剩下的页数就是当前应该播放的页数。同时需要设置跳转到指定页面并再次调用播放页面序号。给来电者。
这里,当我们按下书页时,如果不加以处理,就会出现一团乱七八糟的漩涡。在这里我们必须处理它。我记得PageView定义的时候,最外层包裹着一个GestureDetector。我们需要处理Page被点击拖动水平移动的场景,所以我们有一个场景来处理HorizontalDragDown和onTap这两个回调函数。
onTap用于tap处理,直接携带序列号token来呼叫调用者。
onHorizontalDragDown 用于水平向下拖动。特殊处理为:
void _onHorizontalDragDown(DragDownDetails details) {if (_timer == null) {return;}_releaseTimer();(Duration(seconds: 2));_startTimer();}
每按一次按钮,定时器停止,释放定时器,定时器延迟2秒。如果这段时间有新闻,把它拖进去,再删除。
如果有2秒的延迟并且没有其他处理,则继续预定的播放过程。参见预定的销毁方法:
void _releaseTimer() {if (_timer != null && !) {return;}_timer?.cancel();_timer = null;}
给定外部环境
下一步是将指定进程的调用者需要的参数暴露给外部环境,并在构造时传递:
BannerWidget({Key key,@required this.childWidget,//子视图列表this.enableIndicator = true,//是否允许显示指示器this.initPage = 0,//初始页面序号this.height = 36,//高度this.width = 340,//宽度this.indicatorRadius = 4,//指示器半径this.indicatorColor = Colors.white,//指示器默认颜色this.indicatorSelectedColor = Colors.red,//页面被选中指示器颜色this.scrollDirection = Axis.horizontal,//滚动方向(默认水平)this.indicatorSpaceBetween = 6,//指示器之间的间距this.autoDisplayInterval = 0,//自动播放时间间隔(不设置或设置为0,则不自动播放)页面被展示回调this.indicatorAlign = Alignment.bottomCenter,//指示器位置})//页面被点击回调: super(key: key);
子视图列表必须提供要播放的内容。从上到下:是否显示索引、首页页码、高度、宽度、宽高比、索引颜色、所选索引颜色、滚动方向(默认水平)、指示器之间的间隔、自动播放时间(如果不显示) 。设置或设置为0,不会自动播放)、页面显示时回调、占位符、页面点击时回调。
使用方法
var images = {"","","","","","","","","","","","",};void main() => runApp(BannerWidget(width: 340,height: 56,autoDisplayInterval: 2,childWidget: ((f) {return Image.network(f,width: 340,height: 48,);}).toList(),));
最后一英里
import 'dart:async';import 'package:flutter/';class BannerWidget extends StatefulWidget {BannerWidget({Key key,@required this.childWidget,this.enableIndicator = true,this.initPage = 0,this.height = 36,this.width = 340,this.indicatorRadius = 4,this.indicatorColor = Colors.white,this.indicatorSelectedColor = Colors.red,this.scrollDirection = Axis.horizontal,this.indicatorSpaceBetween = 6,this.autoDisplayInterval = 0,this.onPageSelected,this.indicatorAlign = Alignment.bottomCenter,}): super(key: key);final double width;final double height;final List childWidget;final Axis scrollDirection;final ValueChanged onPageSelected;final ValueChanged onPageClicked;final int initPage;final bool enableIndicator;final Color indicatorSelectedColor;final Color indicatorColor;final double indicatorRadius;final double indicatorSpaceBetween;final int autoDisplayInterval;final Alignment indicatorAlign;@override__BannerWidgetState createState() => __BannerWidgetState();}class __BannerWidgetState extends State {int selectedPage = 0;PageController _controller;Timer _timer;int lastTapDownTime = 0;void onPageChanged(int index) {setState(() {selectedPage = index;});widget?.onPageSelected(index);}void _startTimer() {if ( <= 0) {return;}var oneSec = Duration(seconds: );_timer = new Timer.periodic(oneSec, (Timer timer) {++selectedPage;selectedPage = selectedPage % widget.childWidget.length;_controller?.jumpToPage(selectedPage);onPageChanged(selectedPage);});}void _releaseTimer() {if (_timer != null && !) {return;}_timer?.cancel();_timer = null;}void _onHorizontalDragDown(DragDownDetails details) {if (_timer == null) {return;}_releaseTimer();(Duration(seconds: 2));_startTimer();}void _onPageClicked() {widget?.onPageClicked(selectedPage);}@overridevoid initState() {();_startTimer();}@overrideWidget build(BuildContext context) {_controller = PageController(initialPage: ,);Widget pageView = GestureDetector(onHorizontalDragDown: _onHorizontalDragDown,onTap: _onPageClicked,child: PageView(children: widget.childWidget,scrollDirection: widget.scrollDirection,onPageChanged: onPageChanged,controller: _controller,),);Widget indicatorWidget = Row(mainAxisAlignment: MainAxisAlignment.center,mainAxisSize: MainAxisSize.max,crossAxisAlignment: CrossAxisAlignment.center,children: widget.childWidget.map((f) {int index = (f);Widget indicatorWidget = Container(width: ().width,height: ().height,margin: (right: ),decoration: new BoxDecoration(shape: BoxShape.circle,color: index == selectedPage? widget.indicatorSelectedColor: widget.indicatorColor,),);return indicatorWidget;},).toList(),);Widget stackWidget = widget.enableIndicator? Stack(alignment: AlignmentDirectional.bottomCenter,children: [pageView,Positioned(bottom: 6,child: Align(alignment: widget.indicatorAlign,child: indicatorWidget,),),],): pageView;Widget parent = Directionality(textDirection: TextDirection.ltr,child: Container(width: widget.width, height: widget.height, child: stackWidget));return parent;}@overridevoid dispose() {();_releaseTimer();}}var images = {"","","","","","","","","","","","",};void main() => runApp(BannerWidget(width: 340,height: 56,autoDisplayInterval: 2,childWidget: ((f) {
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
code前端网



发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。