我有一个包含 2 个页面的 PageView,两个页面中的每个页面都有一个自定义的导航器堆栈。
在最初开始时(假设我在第 1 页上加注),当我开始滚动或跳转到第 2 页时(正常情况下)会构建第 2 页。
认为当我在第 2 页并返回到第 1 页时,反之亦然,这些页面保持活动状态,我想处置/杀死它们以强制重建......至少在第 2 页上。
我试过 wantKeepAlive = false
但没有用。
有人可以分享实现这一目标的方法吗。
答案 0 :(得分:2)
如果目标是让我们的小部件在页面前后滑动时重建,我们可以使用 onPageChanged
的 PageView.builder
回调。1
onPageChanged:
将在每次查看页面时运行我们给它的函数。
onPageChanged
链接到重建页面onPageChanged
和 PageView
中的页面重建之间没有内在联系。
onPageChanged
只运行我们给它的任何任意函数,仅此而已。
如果我们希望使用 onPageChanged
重建页面,我们需要自己创建该链接。
ValueNotifier
/ValueListenableBuilder
在此示例中,我们使用 ValueNotifier
(buildCount
变量)通知 ValueListenableBuilder
在 buildCount
更改时重建。 (有关信息,请参阅 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
是另一回事。