Flutter:PageView 示例

这篇实用的文章将引导您了解在 Flutter中实现PageView小部件的几个不同示例。第一个示例简单明了,而第二个示例有点复杂,因为它带有点指示符。在编写代码之前,让我们先了解一下基础知识。

基本面

根据官方文档,PageView 小部件用于创建一个可滚动的列表,逐页工作。最常见的用例之一是轮播/幻灯片图像,您可以在网络上的许多地方或移动应用程序中看到它们。

您可以使用以下构造函数从一个显式的小部件列表构造一个 PageView:

PageView({
  Key? key, 
   Axis scrollDirection = Axis.horizontal, 
   bool reverse = false, 
   PageController? controller, 
   ScrollPhysics? physics, 
   bool pageSnapping = true, 
   ValueChanged<int>? onPageChanged, 
   List<Widget> children = const <Widget>[], 
   DragStartBehavior dragStartBehavior = DragStartBehavior.start, 
   bool allowImplicitScrolling = false, String? restorationId, 
   Clip clipBehavior = Clip.hardEdge, 
   ScrollBehavior? scrollBehavior, 
   bool padEnds = true
})

如果您想实现一个使用按需创建的小部件(例如,从远程服务器加载的动态项目)的 PageView,请使用以下构造函数:

PageView.builder({
  Key? key, 
  Axis scrollDirection = Axis.horizontal, 
  bool reverse = false, 
  PageController? controller, 
  ScrollPhysics? physics, 
  bool pageSnapping = true, 
  ValueChanged<int>? onPageChanged, 
  required IndexedWidgetBuilder itemBuilder, 
  ChildIndexGetter? findChildIndexCallback, 
  int? itemCount, 
  DragStartBehavior dragStartBehavior = DragStartBehavior.start, 
  bool allowImplicitScrolling = false, 
  String? restorationId, 
  Clip clipBehavior = Clip.hardEdge, 
  ScrollBehavior? scrollBehavior, 
  bool padEnds = true
})

为了更好地理解,让我们来看看接下来的例子。

演示

Flutter:PageView 示例

代码

main.dart中的完整源代码及说明:

// kindacode.com
// PageView example
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
        // remove the debug banner
        debugShowCheckedModeBanner: false,
        title: 'KindaCode.com',
        home: KindaCode());
  }
}

class KindaCode extends StatefulWidget {
  const KindaCode({Key? key}) : super(key: key);

  @override
  State<KindaCode> createState() => _KindaCodeState();
}

class _KindaCodeState extends State<KindaCode> {
  // Declare and Initialize the PageController
  final PageController _pageController =
      PageController(initialPage: 0, viewportFraction: 1);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: PageView(
        controller: _pageController,
        children: const [PageOne(), PageTwo(), PageThree()],
      ),
    );
  }

  // Dispose the PageController
  @override
  void dispose() {
    _pageController.dispose();
    super.dispose();
  }
}

// Page One
class PageOne extends StatelessWidget {
  const PageOne({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      alignment: Alignment.center,
      color: Colors.indigo,
      child: const Text(
        'Page 1',
        style: TextStyle(fontSize: 50, color: Colors.white),
      ),
    );
  }
}

// Page Two
class PageTwo extends StatelessWidget {
  const PageTwo({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
        alignment: Alignment.center,
        color: Colors.green,
        child: const Text(
          'Page 2',
          style: TextStyle(fontSize: 50, color: Colors.white),
        ));
  }
}

// Page Three
class PageThree extends StatelessWidget {
  const PageThree({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
        alignment: Alignment.center,
        color: Colors.amber,
        child: const Text(
          'Page 3',
          style: TextStyle(fontSize: 50, color: Colors.black),
        ));
  }
}

带点指示器的 PageView

演示

此示例是对前一个示例的增强。它显示一个带有点指示器的 PageView。每个页面都与一个点相关联。当前页面对应的点将具有与其他点不同的颜色。此外,用户可以通过向左、向右滑动或点击一个点来在页面之间移动。以下是它的工作原理:

Flutter:PageView 示例

代码

main.dart中的完整代码以及注释中的解释:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
        // remove the debug banner
        debugShowCheckedModeBanner: false,
        title: 'KindaCode.com',
        home: KindaCodeDemo());
  }
}

// Construct Dots Indicator

class KindaCodeDemo extends StatefulWidget {
  const KindaCodeDemo({Key? key}) : super(key: key);

  @override
  State<KindaCodeDemo> createState() => _KindaCodeDemoState();
}

class _KindaCodeDemoState extends State<KindaCodeDemo> {
  // declare and initizlize the page controller
  final PageController _pageController = PageController(initialPage: 0);

  // the index of the current page
  int _activePage = 0;

  // this list holds all the pages
  // all of them are constructed in the very end of this file for readability
  final List<Widget> _pages = [
    const PageOne(),
    const PageTwo(),
    const PageThree()
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          // the page view
          PageView.builder(
            controller: _pageController,
            onPageChanged: (int page) {
              setState(() {
                _activePage = page;
              });
            },
            itemCount: _pages.length,
            itemBuilder: (BuildContext context, int index) {
              return _pages[index % _pages.length];
            },
          ),
          // Display the dots indicator
          Positioned(
            bottom: 0,
            left: 0,
            right: 0,
            height: 100,
            child: Container(
              color: Colors.black54,
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: List<Widget>.generate(
                    _pages.length,
                    (index) => Padding(
                          padding: const EdgeInsets.symmetric(horizontal: 10),
                          child: InkWell(
                            onTap: () {
                              _pageController.animateToPage(index,
                                  duration: const Duration(milliseconds: 300),
                                  curve: Curves.easeIn);
                            },
                            child: CircleAvatar(
                              radius: 8,
                              // check if a dot is connected to the current page
                              // if true, give it a different color
                              backgroundColor: _activePage == index
                                  ? Colors.amber
                                  : Colors.grey,
                            ),
                          ),
                        )),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

// Page One
class PageOne extends StatelessWidget {
  const PageOne({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      alignment: Alignment.center,
      color: Colors.pink,
      child: const Text(
        'KindaCode.com',
        style: TextStyle(fontSize: 30, color: Colors.white),
      ),
    );
  }
}

// Page Two
class PageTwo extends StatelessWidget {
  const PageTwo({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
        alignment: Alignment.center,
        color: Colors.green,
        child: const Text(
          'Green Page',
          style: TextStyle(fontSize: 50, color: Colors.white),
        ));
  }
}

// Page Three
class PageThree extends StatelessWidget {
  const PageThree({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
        alignment: Alignment.center,
        color: Colors.blue,
        child: const Text(
          'Blue Page',
          style: TextStyle(fontSize: 50, color: Colors.white),
        ));
  }
}