Flutter速来系列23-3、PageView,去吧,引导页、图片轮播

895 阅读4分钟

Flutter中的PageView

在Flutter应用开发中,我们经常需要实现滑动切换页面的功能,比如引导页、图片轮播等。Flutter提供了一个非常实用的组件来满足我们的需求,那就是PageView

什么是PageView?

PageView是Flutter中的一个滚动组件,它可以让多个页面在水平或垂直方向上滑动切换。每一个页面都是一个单独的Widget,你可以在每个页面中放置任何你想要的内容。

如何使用PageView?

使用PageView非常简单,你只需要将你的页面作为PageView的子组件即可。下面是一个简单的例子:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('PageView Demo'),
        ),
        body: PageView(
          children: <Widget>[
            Container(color: Colors.red), // 第一页
            Container(color: Colors.green), // 第二页
            Container(color: Colors.blue), // 第三页
          ],
        ),
      ),
    );
  }
}

iShot_2023-07-11_11.30.55.gif

在这个例子中,我们创建了一个包含三个页面的PageView,每个页面都是一个颜色不同的Container。你可以通过滑动来切换页面。

PageView的特性

PageView有一些重要的特性需要我们了解:

Controller

通过控制器(controller)属性,我们可以控制PageView的当前页面。

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  final controller = PageController(initialPage: 1); // 初始页面为第二页

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('PageView Demo - Controller'),
        ),
        body: PageView(
          controller: controller, // 设置控制器
          children: <Widget>[
            Container(color: Colors.red),
            Container(color: Colors.green),
            Container(color: Colors.blue),
          ],
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            controller.animateToPage(2, duration: Duration(seconds: 1), curve: Curves.easeInOut); // 切换到第三页
          },
          child: Icon(Icons.arrow_forward),
        ),
      ),
    );
  }
}

iShot_2023-07-11_11.25.45.gif

在这个例子中,我们创建了一个PageController,并将其设置为PageView的控制器。然后我们可以通过调用PageController的animateToPage方法来切换到指定页面。

Physics

通过物理(physics)属性,我们可以定义滚动的物理行为,比如滚动速度、弹性效果等。

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('PageView Demo - Physics'),
        ),
        body: PageView(
          physics: BouncingScrollPhysics(), // 设置物理行为为弹性滚动
          children: <Widget>[
            Container(color: Colors.red),
            Container(color: Colors.green),
            Container(color: Colors.blue),
          ],
        ),
      ),
    );
  }
}

iShot_2023-07-11_11.27.17.gif

在这个例子中,我们设置了物理行为为BouncingScrollPhysics,这会使得滚动有一个弹性的效果。

onPageChanged

通过onPageChanged回调,我们可以在页面切换时执行一些操作。

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('PageView Demo - onPageChanged'),
        ),
        body: PageView(
          onPageChanged: (page) {
            print('Current page: $page'); // 打印当前页面
          },
          children: <Widget>[
            Container(color: Colors.red),
            Container(color: Colors.green),
            Container(color: Colors.blue),
          ],
        ),
      ),
    );
  }
}

某一些的打印:

Current page: 1
Current page: 2
Current page: 1
Current page: 0
Current page: 1
……

在这个例子中,我们设置了onPageChanged回调,每当页面切换时,我们都会打印当前的页面。

PageView生命周期和页面缓存

生命周期

在Flutter中,每个Widget都有自己的生命周期。当你滑动PageView时,当前页面的Widget会被创建(调用build方法),当你滑动离开当前页面时,当前页面的Widget会被销毁(调用dispose方法)。这就是PageView的生命周期。

这种生命周期模型使得PageView在处理大量数据时具有很高的性能,因为只有当前页面的Widget会被创建,其他页面的Widget会被销毁,这大大减少了内存的使用。

然而,这种生命周期模型也有一个缺点,那就是当你返回到一个已经被销毁的页面时,这个页面的Widget需要重新创建,这可能会导致一些性能问题,特别是当你的页面Widget非常复杂时。


viewportFraction

你可以通过PageControllerviewportFraction属性来控制缓存的页面数量。 viewportFraction属性的总结:

viewportFraction显示效果
0.0禁用滚动,只显示一个页面,不能通过滑动来切换页面。
1.0默认值。每个页面都会占满整个PageView的可视区域,可以通过滑动来切换页面。
大于0.0且小于1.0每个页面占据整个可视区域的指定比例,允许同时显示多个页面,通过滑动来切换部分或全部页面。

通过调整viewportFraction属性的值,你可以控制每个页面在PageView中所占的比例。默认情况下,每个页面会占满整个可视区域,允许通过滑动来切换页面。当viewportFraction的值介于0.0和1.0之间时,每个页面的宽度会相应调整,允许显示多个页面并通过滑动来切换它们。

需要注意的是,较小的viewportFraction值会导致页面变小,可能需要滑动更多次才能看到完整的页面内容。较大的viewportFraction值则会使页面更大,可能一次滑动就可以切换到下一个页面。

根据你的设计需求和用户体验,选择适当的viewportFraction值可以实现不同的页面显示效果和交互方式。

然而,这种缓存机制也有一个缺点,那就是它会消耗更多的内存。如果你的页面非常复杂,或者你有很多页面需要缓存,那么这可能会导致内存压力增大。在这种情况下,你可能需要考虑使用其他的方法来优化你的页面,比如使用ListView.builder或者GridView.builder来延迟构建你的页面。