首页 > 解决方案 > 如何在 Flutter 中处理/杀死 PageView 中的页面

问题描述

我有一个有 2 页的 PageView,我有一个自定义的导航器堆栈用于两个页面。

在最初的开始(假设我在第 1 页上加注星标),当我开始滚动或跳转到第 2 页时(正常),第 2 页就建立了。

想当我在第 2 页并返回第 1 页时,反之亦然,这些页面保持活动状态,我想处置/杀死它们以强制重建..至少在第 2 页上。

我试过wantKeepAlive = false但没有用。

有人可以分享实现这一目标的方法吗?

标签: flutterflutter-layout

解决方案


刷卡时重建

如果目标是告诉我们的小部件在页面被来回滑动时重建,我们可以onPageChanged使用PageView.builder. 1

onPageChanged:每次查看页面时都会运行我们给它的函数。

链接onPageChanged到重建页面

在. onPageChanged_PageView

onPageChanged只是运行我们给它的任意函数,仅此而已。

如果我们希望重建页面,onPageChanged我们需要自己创建该链接。

ValueNotifier/链接ValueListenableBuilder

在此示例中,我们使用ValueNotifier(buildCount变量) 来通知在更改ValueListenableBuilder时进行重建buildCount。(有关信息,请参阅Flutter 文档。)

每次我们滑动页面时,buildCount都会增加,ValueListenableBuilder页面中的 会重建,显示新的总数:

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

class PageViewRebuildPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('PageView Stream Rebuild'),
      ),
      body: PageViewRebuildExample()
    );
  }
}

class PageViewRebuildExample extends StatelessWidget {
  final List<String> contents = ['One', 'Two', 'Three'];
  final ValueNotifier<int> buildCount = ValueNotifier<int>(0);

  @override
  Widget build(BuildContext context) {
    print('Example built');
    return Center(
      child: PageView.builder(
        itemCount: contents.length,
        onPageChanged: (page) {
          print('PageChanged $page');
          buildCount.value++;
        },
        itemBuilder: (context, index) {
          return Container(
            alignment: Alignment.center,
            margin: EdgeInsets.symmetric(vertical: 40, horizontal: 20),
            color: Colors.lightBlueAccent,
            child: ValueListenableBuilder(
              valueListenable: buildCount,
                    // bldCnt here ↓↓ is buildCount.value
              builder: (context, bldCnt, child) =>
                  // ↓ YOUR STUFF GOES HERE ↓
                  Text('Page ${contents[index]} : $bldCnt',
                      style: TextStyle(fontSize: 30)),
            ),
          );
        },
      ),
    );
  }
}

为了根据您的目的调整此示例,您将替换Widget的builder:部分。ValueListenableBuilder它将在每次滑动时重建。


附录

如果您想知道滑动手势期间页面的精确位置,我们可以提供PageControllerto PageView,将侦听器附加到该控制器,然后侦听controller.page输出:

class PageViewRebuildExample extends StatefulWidget {
  @override
  _PageViewRebuildExampleState createState() => _PageViewRebuildExampleState();
}

// Switched to StatefulWidget so we can add listener & dispose
class _PageViewRebuildExampleState extends State<PageViewRebuildExample> {
  final List<String> contents = ['One', 'Two', 'Three'];
  final ValueNotifier<int> buildCount = ValueNotifier<int>(0);
  final PageController controller = PageController(); // ← our new controller

  @override
  void initState() {
    super.initState();
    controller.addListener(() { // ← add a listener in onInit
      print('Precise page position ${controller.page}');
    });
  }
  
  @override
  void dispose() {
    controller.dispose(); // don't forget to dispose
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    print('Example built');

    return Center(
      child: PageView.builder(
        itemCount: contents.length,
        controller: controller, // ← PageController provided here
        onPageChanged: (page) {
          print('PageChanged $page');
          buildCount.value++;
        },

上面示例监听器的输出是(剪短):

I/flutter (14528): Precise page position 0.001861572265625
I/flutter (14528): Precise page position 0.006500244140625
I/flutter (14528): Precise page position 0.01019287109375
I/flutter (14528): Precise page position 0.012054443359375
... <snip>
I/flutter (14528): Precise page position 0.45981356897799835
I/flutter (14528): Precise page position 0.5179874247450384
I/flutter (14528): PageChanged 1
I/flutter (14528): Precise page position 0.5743095749455654
I/flutter (14528): Precise page position 0.6269737660740682
... <snip>
I/flutter (14528): Precise page position 0.9986377335325707
I/flutter (14528): Precise page position 0.9988375372072605
I/flutter (14528): Precise page position 0.9990080727700607
I/flutter (14528): Precise page position 1.0


1可能有许多其他方法可以做到这一点,这只是一种方法。例如,Stream用于将事件从内部发送onPageChangedStreamBuilder内部itemBuilder是另一回事。


推荐阅读