Flutter PageView(轮动图)

发布时间 2024-01-04 23:28:56作者: 鲤斌
Flutter中的轮动图以及抖音上下滑页切换视频功能等等,这些都可以通过 PageView 轻松实现

PageView常见属性:

PageView 的使用

class MyPage extends StatefulWidget {
  const MyPage({super.key});

  @override
  State<MyPage> createState() => _MyPageState();
}

class _MyPageState extends State<MyPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: PageView(
      scrollDirection: Axis.vertical, //垂直滑动  默认水平滑动
      children: const [
        Center(
          child: Text("1"),
        ),
        Center(
          child: Text("2"),
        ),
        Center(
          child: Text("3"),
        ),
        Center(
          child: Text("4"),
        ),
      ],
    ));
  }
}

PageView.builder

class MyPage extends StatefulWidget {
  const MyPage({super.key});

  @override
  State<MyPage> createState() => _MyPageState();
}

class _MyPageState extends State<MyPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: PageView.builder(
      itemCount: 5,
      scrollDirection: Axis.vertical, // 滑动方向为垂直方向
      itemBuilder: (BuildContext context, int index) {
        return Center(
          child: Text("第$index页"),
        );
      },
    ));
  }
}

PageView上拉无限加载的实现思路 

class PageViewPage extends StatefulWidget {
  const PageViewPage({super.key});
  @override
  State<PageViewPage> createState() => _PageViewPageState();
}

class _PageViewPageState extends State<PageViewPage> {
  final List<Widget> _list = []; // 创建一个名为_list的空Widget列表

  @override
  void initState() {
    // 在初始化阶段运行
    super.initState();
    for (var i = 0; i < 3; i++) {
      _list.add(MyPage(text: "$i")); // 将一个带有相应文本的MyPage小部件添加到_list中
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: PageView(
      scrollDirection: Axis.vertical, // 设置PageView的滚动方向为垂直方向
      onPageChanged: (index) {
        // 每当页面更改时调用的回调函数

        print("-----$index"); // 打印当前页面的索引
        print(_list.length); // 打印_list中的部件数
        if (index + 1 == _list.length) {
          // 如果当前页面是_list的倒数第二个
          setState(() {
            // 在setState中更改_list
            for (var i = 0; i < 3; i++) {
              // 添加10个新的MyPage小部件到_list中
              _list.add(MyPage(text: "$i"));
            }
          });
        }
      },
      children: _list, // 将_list中的小部件作为PageView的子部件
    ));
  }
}

class MyPage extends StatefulWidget {
  final String text;
  const MyPage({super.key, required this.text});
  @override
  State<MyPage> createState() => _MyPageState();
}

class _MyPageState extends State<MyPage> {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text(widget.text,
          style: Theme.of(context).textTheme.headline1), // 显示小部件的文本
    );
  }
}

PageView 实现一个无限轮播的轮播图

import 'package:flutter/material.dart';

class PageViewPage extends StatefulWidget {
  const PageViewPage({super.key});
  // PageViewPage组件的构造函数
  @override
  State<PageViewPage> createState() => _PageViewPageState();
  // 创建并返回PageViewPage组件对应的状态
}
class _PageViewPageState extends State<PageViewPage> {
  List<Widget> pageList = [];
  // 定义一个Widget类型的列表pageList
  @override
  void initState() {
    super.initState();
    // 重写父类的initState()函数
    List listData = [
      // 创建一个列表listData包含多个图片URL
      {
        "imageUrl": 'https://www.itying.com/images/flutter/1.png',
      },
      {
        "imageUrl": 'https://www.itying.com/images/flutter/2.png',
      },
      {
        "imageUrl": 'https://www.itying.com/images/flutter/3.png',
      },
    ];
    for (int i = 0; i < listData.length; ++i) {
      // 遍历listData
      pageList.add(PicturePage(
        url: listData[i]["imageUrl"],
      ));
      // 根据遍历结果创建PicturePage组件,并将其添加到pageList列表中
    }
  }
  @override
  Widget build(BuildContext context) {
    // 重写父类的build()函数
    return Scaffold(
      body: ListView(
        // 在Scaffold的主体部分创建一个ListView组件
        children: [Swiper(pageList: pageList)],
        // 将Swiper组件添加到ListView的子部件列表中
      ),
    );
  }
} //Swiper组件
class Swiper extends StatefulWidget {
  final double width;
  final double height;
  final List<Widget> pageList;
  const Swiper(
      {super.key,
      this.width = double.infinity,
      this.height = 200,
      required this.pageList});
  @override
  State<Swiper> createState() => _SwiperState();
}

class _SwiperState extends State<Swiper> {
  int _currentPageIndex = 0;
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        SizedBox(
          width: double.infinity,
          height: 200,
          child: PageView.builder(
              onPageChanged: (int index) {
                // 当页面改变时调用的回调函数
                setState(() {
                  _currentPageIndex = index % (widget.pageList.length);
                });
              },
              itemCount: 10000, // 打算生成的页面数,这里写得非常大,因此可以实现无限循环滚动
              itemBuilder: (context, index) {
                return widget.pageList[index % (widget.pageList.length)];
              }),
        ),
        Positioned(
          //圆点
          bottom: 10, //位置
          left: 0, //位置
          right: 0, //位置
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: List.generate(widget.pageList.length, (i) {
              // 利用List.generate方法生成指定数量的圆点
              return Container(
                margin: const EdgeInsets.fromLTRB(2, 0, 2, 0),
                width: 10,
                height: 10,
                decoration: BoxDecoration(
                    shape: BoxShape.circle,
                    color: _currentPageIndex == i ? Colors.blue : Colors.grey),
              );
            }).toList(),
          ),
        ),
      ],
    );
  }
}
// PicturePage 图片页面
class PicturePage extends StatefulWidget {
  final String url;
  final double width;
  final double height;
  const PicturePage(
      {super.key,
      required this.url,
      this.width = double.infinity,
      this.height = 200});
  @override
  State<PicturePage> createState() => _PicturePageState();
}

class _PicturePageState extends State<PicturePage> {
  @override
  Widget build(BuildContext context) {
    print(widget.url);
    return SizedBox(
      width: widget.width,
      height: widget.height,
      child: Image.network(widget.url, fit: BoxFit.cover),
    );
  }
}