Flutter——PageView

290 阅读1分钟
  • PageView

PageView类似看小说或抖音的页面
scrollDirection: Axis.vertical, //滑动方向
PageView(
   children: [
       包裹的页面
   ]
   )
example无限加载:
class PageViewFullPage extends StatefulWidget {
  const PageViewFullPage({super.key});

  @override
  State<PageViewFullPage> createState() => _PageViewFullPageState();
}

class _PageViewFullPageState extends State<PageViewFullPage> {
  List<Widget> list = [];
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    for (var i = 0; i < 10; i++) {
      list.add(Center(
        child: Text(
          "第${i + 1}屏",
          style: const TextStyle(fontSize: 60),
        ),
      ));
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: PageView(
        scrollDirection: Axis.vertical,
        children: list,
        onPageChanged: (index) {
          print(index);
          if (index + 2 == list.length) {
            setState(() {
              for (var i = 0; i < 10; i++) {
                list.add(Center(
                  child: Text(
                    "第${i + 1}屏",
                    style: const TextStyle(fontSize: 60),
                  ),
                ));
              }
            });
          }
        },
      ),
    );
  }
}

  • PageView实现轮播图

细节:PageView尽量外层包裹一下,不然可能会出现控制不了高度
定位技巧:能占满行
left: 0,
right: 0,
bottom: 2,  
PageController 实现轮播
这里有用到定时器:Timer
dispose 用于释放资源,以便在Widget被删除之前,可以清除它们。
cancel用于取消异步操作。它通常与FutureStream一起使用,以便在不需要结果时,可以停止异步操作。
1、图片数据文件
class PageViewSwiper extends StatefulWidget {
  const PageViewSwiper({super.key});

  @override
  State<PageViewSwiper> createState() => _PageViewSwiperState();
}

class _PageViewSwiperState extends State<PageViewSwiper> {
  List<String> list = [];

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    list = const [
      "https://www.itying.com/images/flutter/1.png",
      "https://www.itying.com/images/flutter/2.png",
      "https://www.itying.com/images/flutter/3.png",
    ];
    // //创建定时器
    // Timer t = Timer.periodic(const Duration(seconds: 3), (timer) {
    //   print("zhixing....");
    // });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("pageview-Swiper"),
      ),
      body: ListView(children: [Swiper(list: list,)]),
    );
  }
}

2、轮播文件
class Swiper extends StatefulWidget {
  final double width;
  final double height;
  final List<String> list;
  const Swiper(
      {super.key,
      this.height = 200,
      this.width = double.infinity,
      required this.list});

  @override
  State<Swiper> createState() => _SwiperState();
}

class _SwiperState extends State<Swiper> {
  int _currentIndex = 0;
  List<Widget> pageList = [];
  late PageController _pageController;
  late Timer timer;
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    for (var i = 0; i < widget.list.length; i++) {
      pageList.add(ImagePage(
          width: widget.width, height: widget.height, src: widget.list[i]));
    }
    _pageController = PageController(initialPage: 0);
    timer = Timer.periodic(const Duration(seconds: 3), (t) {
      _pageController.animateToPage((_currentIndex + 1) % pageList.length,
          duration: const Duration(microseconds: 1000), curve: Curves.linear);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        SizedBox(
          height: widget.height,
          child: PageView.builder(
              controller: _pageController,
              onPageChanged: (index) {
                setState(() {
                  _currentIndex = index % pageList.length;
                });
              },
              itemCount: 1000,
              itemBuilder: (context, index) {
                return pageList[index % pageList.length];
              }),
        ),
        Positioned(
            left: -5,
            right: 0,
            bottom: 2,
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: List.generate(pageList.length, (index) {
                return Container(
                  margin: const EdgeInsets.all(5),
                  height: 10,
                  width: 10,
                  decoration: BoxDecoration(
                      color: _currentIndex == index ? Colors.blue : Colors.grey,
                      borderRadius: BorderRadius.circular(5)),
                );
              }).toList(),
            ))
      ],
    );
  }
  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    timer.cancel();
    _pageController.dispose();
  }
}

class ImagePage extends StatelessWidget {
  final double width;
  final double height;
  final String src;
  const ImagePage(
      {super.key,
      this.width = double.infinity,
      this.height = 200,
      required this.src});
  @override
  Widget build(BuildContext context) {
    return Container(
      width: width,
      height: height,
      child: Image.network(
        src,
        fit: BoxFit.cover,
      ),
    );
  }
}

  • AutomaticKeepAliveClientMixin 缓存

with AutomaticKeepAliveClientMixin 一下
example:
class MyContainer extends StatefulWidget {
  final int num;
  const MyContainer({super.key, required this.num});

  @override
  State<MyContainer> createState() => _MyContainerState();
}

class _MyContainerState extends State<MyContainer>
    with AutomaticKeepAliveClientMixin {
  @override
  Widget build(BuildContext context) {
    print(widget.num); //默认没缓存,每次都会执行build
    return Center(
      child: Text(
        "第${widget.num}屏",
        style: Theme.of(context).textTheme.headlineLarge,
      ),
    );
  }

  @override
  // TODO: implement wantKeepAlive
  bool get wantKeepAlive => true; //true 表示缓存页面
}