Code前端首页关于Code前端联系我们

Flutter制作图片横幅轮播

terry 2年前 (2023-09-23) 阅读数 83 #移动小程序

制作店面应用时,需要用到轮播。我看到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被点击拖动水平移动的场景,所以我们有一个场景来处理Horizo​​ntalDragDown和onTap这两个回调函数。

onTap用于tap处理,直接携带序列号token来呼叫调用者。

onHorizo​​ntalDragDown 用于水平向下拖动。特殊处理为:

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);  }
  @override  void initState() {    ();    _startTimer();  }
  @override  Widget 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;  }
  @override  void dispose() {    ();    _releaseTimer();  }}
var images = {  "",  "",  "",  "",  "",  "",  "",  "",  "",  "",  "",  "",};
void main() => runApp(BannerWidget(      width: 340,      height: 56,      autoDisplayInterval: 2,      childWidget: ((f) {   

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

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

热门