如何在颤振中处理/杀死页面视图中的页面

时间:2021-04-25 13:44:00

标签: flutter flutter-layout

我有一个包含 2 个页面的 PageView,两个页面中的每个页面都有一个自定义的导航器堆栈。

在最初开始时(假设我在第 1 页上加注),当我开始滚动或跳转到第 2 页时(正常情况下)会构建第 2 页。

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

我试过 wantKeepAlive = false 但没有用。

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

1 个答案:

答案 0 :(得分:2)

在滑动时重建

如果目标是让我们的小部件在页面前后滑动时重建,我们可以使用 onPageChangedPageView.builder 回调。1

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

onPageChanged 链接到重建页面

onPageChangedPageView 中的页面重建之间没有内在联系。

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

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

链接到 ValueNotifier/ValueListenableBuilder

在此示例中,我们使用 ValueNotifierbuildCount 变量)通知 ValueListenableBuilderbuildCount 更改时重建。 (有关信息,请参阅 Flutter Docs。)

每次我们滑动页面时,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)),
            ),
          );
        },
      ),
    );
  }
}

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


附录

如果您想在滑动手势期间知道页面的精确位置,我们可以向 PageController 提供 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 将事件从 onPageChanged 发送到 StreamBuilder 内的 itemBuilder 是另一回事。