Flutter輪播圖效果、Flutter輪播圖Demo

語言: CN / TW / HK

在碼農的世界裡,優美的應用體驗,來源於程式設計師對細節的處理以及自我要求的境界,年輕人也是忙忙碌碌的碼農中一員,每天、每週,都會留下一些腳印,就是這些創作的內容,有一種執著,就是不知為什麼,如果你迷茫,不妨來瞅瞅碼農的軌跡。


本文章的效果圖:
在這裡插入圖片描述

1 基本使用

已將輪播圖封裝成 BannerWidget 大家可以直接拷貝使用:

  • 自動輪播
  • 手指按下時停止輪播

基本使用程式碼如下:

class HomeItemDemoPage extends StatefulWidget {
   
   
  @override
  _HomeItemDemoPageState createState() => _HomeItemDemoPageState();
}

class _HomeItemDemoPageState extends State<HomeItemDemoPage> {
   
   
  
  List<String> _list = [
    "assets/images/banner1.png",
    "assets/images/banner1.png",
    "assets/images/banner1.png",
    "assets/images/banner1.png",
    "assets/images/banner1.png"
  ];

  @override
  Widget build(BuildContext context) {
   
   
    return Scaffold(
      appBar: AppBar(
        title: Text("Demo"),
      ),
      backgroundColor: Colors.white,

      ///填充佈局
      body:  BannerWidget(
              imageList: _list,
            ),
    );
  }
}

2 BannerWidget 的定義

首先是定義

class BannerWidget extends StatefulWidget {
   
   
  final List<String> imageList;

  ///輪播的時間
  final Duration loopDuration;

  BannerWidget({
   
   
    //必傳引數
    @required this.imageList,
    //輪播時間
    this.loopDuration = const Duration(seconds: 3),
  });

  @override
  _BannerWidgetState createState() => _BannerWidgetState();
}

class _BannerWidgetState extends State<BannerWidget> {
   
   
  //顯示的輪播總頁數
  int _total = 5;
  //當前顯示的頁數
  int _current = 1;
  //計時器
  Timer _timer;
  PageController _pageController;

  @override
  void initState() {
   
   
    super.initState();
    //輪播圖個數
    _total = widget.imageList.length;
    //輪播控制器
    _pageController = new PageController(initialPage: 5000);
    //開始輪播
    startLoopFunction();
  }

  @override
  void dispose() {
   
   
    _timer.cancel();
    super.dispose();
  }
}

然後 build 中的構建如下:

  @override
  Widget build(BuildContext context) {
   
   
    //輪播 圖
    return Container(
      color: Colors.red,
      height: 200,
      width: MediaQuery.of(context).size.width,
      child: GestureDetector(
        //手指按下的回撥
        onTapDown: (TapDownDetails details) {
   
   
          LogUtils.e("手指按下,停止輪播");
          stopLoopFunction();
        },
        //手指抬起的回撥
        onTap: () {
   
   
          LogUtils.e("手指抬起,開始輪播");
          startLoopFunction();
        },
        //手指按下後滑動移出的回撥
        onTapCancel: () {
   
   
          LogUtils.e("手指移出,開始輪播");
          startLoopFunction();
        },
        child: buildStack(),
      ),
    );
  }

然後開始輪播與結束輪播的方法定義

  //定義開始輪播的方法
  void startLoopFunction() {
   
   
    //定時器
    _timer = Timer.periodic(widget.loopDuration, (timer) {
   
   
      //滑動到下一頁
      _pageController.nextPage(
        curve: Curves.linear,
        duration: Duration(
          milliseconds: 200,
        ),
      );
    });
  }

  //定義停止輪播的方法
  void stopLoopFunction() {
   
   
    if (_timer.isActive) {
   
   
      _timer.cancel();
    }
  }

然後輪播圖與指示器是層疊在一起的

  Stack buildStack() {
   
   
    return Stack(
      children: [
        //第一層 輪播
        Positioned.fill(
          child: PageView.builder(
            //控制器
            controller: _pageController,
            //總頁數
            itemCount: 10000,
            //滑動時回撥 value 當前顯示的頁面
            onPageChanged: (value) {
   
   
              setState(() {
   
   
                _current = value % widget.imageList.length;
              });
            },
            itemBuilder: (BuildContext context, int index) {
   
   
              String image = widget.imageList[index % widget.imageList.length];
              return Image.asset(
                image,
                fit: BoxFit.fill,
              );
            },
          ),
        ),
        //第二層 指示器
        Positioned(
          right: 14,
          bottom: 14,
          child: buildContainer(),
        ),
      ],
    );
  }

右下角對齊的指示器

  Container buildContainer() {
   
   
    return Container(
      alignment: Alignment.center,
      width: 50,
      height: 24,
      decoration: BoxDecoration(
          color: Colors.grey[200].withOpacity(0.5),
          //設定圓角
          borderRadius: BorderRadius.all(Radius.circular(12))),
      child: Text(
        "$_current/$_total",
        textAlign: TextAlign.center,
      ),
    );
  }

完畢

不侷限於思維,不侷限語言限制,才是程式設計的最高境界。

以小編的性格,肯定是要錄製一套影片的,隨後會上傳

有興趣 你可以關注一下 西瓜影片 — 早起的年輕人

在這裡插入圖片描述

本文同步分享在 部落格“早起的年輕人”(CSDN)。
如有侵權,請聯絡 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。