likes
comments
collection
share

Flutter 中 PageView 的使用详解 | Flutter Widgets

作者站长头像
站长
· 阅读数 17

前言

上一篇我们聊了 IndexedStack 实现了一个简单的项目主页基础骨架的搭建,这一篇我们还是做这个主页骨架,但是是使用 PageView 来做并且附带了一些滑动效果。

看效果

先看看下面的效果一般是 App 的简单主页骨架,你知道使用 PageView 怎么实现的吗?Flutter 中 PageView 的使用详解 | Flutter Widgets这里相比上个 IndexedStack 版本有几个细节上的不同之处

  • 页面可以滑动来切换
  • 单独详情页可以改变状态并保持(count)
  • 滑动页面时导航栏也是跟着变的

PageView(页面布局)

看名字就是知道他是专门来做页面布局使用的,这篇我们要一步一步实现上面的效果,如果你看过上篇的内容了,那么这篇会快就可以学会。

主体内容

上篇我们主体内容是添加 IndexedStack ,这篇我们改变成 PageView 即可,然后会新增一个控制器和页面滑动改变后的方法实现

/// PageView 页面
class PageViewPage extends StatefulWidget {
  PageViewPage({Key? key}) : super(key: key);

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

class _PageViewPageState extends State<PageViewPage> {
  // 当前子项索引
  int currentIndex = 0;
  // 子项集
  late List<Widget> children;
  // 控制器
  late PageController _controller;

  @override
  void initState() {
    super.initState();
    // 初始化子项集合
    children = [
      PageDetails(title: '首页'),
      PageDetails(title: '消息'),
      PageDetails(title: '我的'),
    ];
    // 初始化控制器
    _controller = PageController();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('PageView - ZeroFlutter'),
      ),
      // 这里改为 PageView
      body: PageView(
        // 设置控制器
        controller: _controller,
        // 设置子项集
        children: children,
        // 添加页面滑动改变后,去改变索引变量刷新页面来更新底部导航
        onPageChanged: (value) {
          currentIndex = value;
          setState(() {});
        },
      ),
      // 底部导航栏
      bottomNavigationBar: [...],
    );
  }
}

子项页面内容

这里因为我们的页面内容肯定不是一成不变的,所以这篇我们将 PageDetails 继承自 StatefulWidget ,然后添加了 count 变量用于设置点击的次数。

/// 页面详情
class PageDetails extends StatefulWidget {
  PageDetails({Key? key, required this.title}) : super(key: key);
  final String title;

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

class _PageDetailsState extends State<PageDetails> {
  int count = 0;
  @override
  Widget build(BuildContext context) {
    // 这里的打印可以记录一下,后面会用到
    print('PageDetails build title:${widget.title}');
    return Scaffold(
      body: GestureDetector(
        onTap: () {
          count += 1;
          setState(() {});
        },
        child: Center(
          child: Text('${widget.title} count:$count'),
        ),
      ),
    );
  }
}

底部导航

这里的底部导航当点击时,我们增加了一个控制器跳转页面的操作。

BottomNavigationBar(
  // 当前页面索引
  currentIndex: currentIndex,
  // 导航子项集
  items: [
    // 导航子项
    BottomNavigationBarItem(
      // 图标
      icon: Icon(Icons.home),
      // 文字内容
      label: '首页',
    ),
    BottomNavigationBarItem(
      icon: Icon(Icons.message_rounded),
      label: '消息',
    ),
    BottomNavigationBarItem(
      icon: Icon(Icons.people),
      label: '我的',
    ),
  ],
  onTap: (value) {
    // 点击事件,用于改变当前索引,然后刷新
    currentIndex = value;
    setState(() {});
    // 通过控制器实现跳转页面
    _controller.jumpToPage(currentIndex);
  },
)

运行效果

这样我们基础骨架就实现完毕,看下面的效果Flutter 中 PageView 的使用详解 | Flutter Widgets

优化页面

细心的你会发现上图页面计数器在页面切换后又归零了,我们实际项目肯定是页面继续保持上次的状态,下面看看怎么优化吧。

保持页面状态

Flutter 早就为我们考虑好了这种情况,真正当我们遇到的时候才会去搜索学习。

/// 页面详情
class PageDetails extends StatefulWidget {
  PageDetails({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  _PageDetailsState createState() => _PageDetailsState();
}
/// 这里混入了 AutomaticKeepAliveClientMixin
class _PageDetailsState extends State<PageDetails>
    with AutomaticKeepAliveClientMixin {
  int count = 0;
  @override
  Widget build(BuildContext context) {
    super.build(context);
    // 这里的打印可以记录一下,后面会用到
    print('PageDetails build title:${widget.title}');
    return Scaffold(
      body: GestureDetector(
        onTap: () {
          count += 1;
          setState(() {});
        },
        child: Center(
          child: Text('${widget.title} count:$count'),
        ),
      ),
    );
  }
	// 设置 true 期望保持页面状态
  @override
  bool get wantKeepAlive => true;
}
  • 我们先看 9~11 行,with(混入)了一个 AutomaticKeepAliveClientMixinmixin
  • 31~32 行,覆写了 get wantKeepAlive 方法,返回 true 来保持页面状态

看看现在的效果

Flutter 中 PageView 的使用详解 | Flutter Widgets到这里我们就实现带有切换效果的项目页面主骨架啦,如果觉得有帮助到你记得点击关注哦

源码仓库

基于 Flutter 🔥 最新版本

参考链接

关注专栏

  • 此文章已收录到下面👇 的专栏,可以直接关注
  • 更多文章继续阅读|系列文章持续更新

👏 欢迎点赞➕收藏➕关注,有任何问题随时在下面👇评论,我会第一时间回复哦