在显示的第一页上方,我显示了一条消息,用户可以向左滑动以转到下一页。在onPageChanged中,我设置了一个bool来关闭消息并调用setState。当我滑动到第1页时,在调用setState的那一刻,页面重置为第0页。
当我删除条件文本时,页面正常滑动。
DartPad gist:https://dartpad.dev/?id=e30a98e4bc531d9cdc93780b6e47f972
这是一个bug还是我错过了什么?
完整的示例代码如下:
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
void main() {
runApp(PageViewTestScreen());
}
class PageViewTestScreen extends StatefulWidget {
PageViewTestScreen({super.key});
@override
State<PageViewTestScreen> createState() => _PageViewTestScreenState();
}
class _PageViewTestScreenState extends State<PageViewTestScreen> {
PageController pageController = PageController(initialPage: 0);
bool lastPage = false;
bool userHasSlided = false;
int numberOfPages = 5;
@override
void initState() {
super.initState();
}
void onPageChanged(int index) {
userHasSlided = true;
lastPage = index == levensgebieden.length-1;
setState(() {});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
floatingActionButton: lastPage
? FloatingActionButton(
onPressed: () {},
child: Icon(Icons.check),
)
: null,
appBar: AppBar(
foregroundColor: Colors.white,
title: const Text("PageView bug?"),
),
body: ListView(
children: [
const Text("Here are some pages"),
const SizedBox(height: 6),
if (!userHasSlided) const Text("Swipe left to continue."),
SizedBox(
height: 500,
child: PageView(
scrollBehavior: const ScrollBehavior().copyWith(dragDevices: {
PointerDeviceKind.touch,
PointerDeviceKind.mouse,
PointerDeviceKind.stylus,
}),
controller: pageController,
onPageChanged: (int index) {
onPageChanged(index);
},
children: [
for (int i = 0; i < 5; i++) card(i),
],
),
)
],
),
),
);
}
Widget card(int index) {
return Card(
child: SizedBox(
height: 500, width: 200, child: Center(child: Text("Page: $index"))),
);
}
}
字符串
2条答案
按热度按时间csbfibhn1#
对于这种情况,提供
key
有助于元素树。字符串
有关Keys.的更多信息
quhf5bfb2#
这是意料之中的,因为
userHasSlided
改变的那一刻,ListView
的子元素也改变了,这触发了一个小部件重建。由于PageView
不是一个常量,它也被重建。重建中断了用户已经完成的滑动进度,因此将页面重置为0。您可以尝试在其他地方(
ListView
之外)添加条件大小写,也许在AppBar
中,并删除ListView
中的条件文本,您会注意到PageView
将按预期工作。这是因为PageView
没有被重建。