为什么Flutter PageView在setState后重置为第0页

问题描述 投票:0回答:1

在显示的第一页上方,我显示一条消息,用户可以向左滑动以转到下一页。在 onPageChanged 中,我设置了一个布尔值来关闭消息并调用 setState。当我滑动到第 1 页时,在调用 setState 的那一刻,页面重置为第 0 页。

当我删除条件文本时,页面会正常滑动。

DartPad 要点:https://dartpad.dev/?id=e30a98e4bc531d9cdc93780b6e47f972

这是一个错误还是我错过了什么?

完整示例代码如下:

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"))),
    );
  }
}
flutter dart setstate flutter-pageview
1个回答
0
投票

这是预期的,因为当

userHasSlided
发生变化时,该
ListView
的子级也发生了变化,这会触发小部件重建。由于
PageView
不是常数,因此它也会被重建。重建会中断用户的滑动进度,从而将页面重置为 0。

您可以尝试在其他地方(

ListView
之外)添加条件情况,也许在
AppBar
中,并删除
ListView
中的条件文本,您会注意到
PageView
将按预期工作。这是因为
ListView
没有被重建。

© www.soinside.com 2019 - 2024. All rights reserved.