我实施了一个类似于thisperspective_page_view.我更新了代码到新的Flutter 版本,一切工作正常.

问题是,我希望这PageView分能有infinite loop分.

我try 了this个问题的多种不同解决方案,但都没有奏效.他们都把我的观点搞砸了.

我觉得这应该是可能的,但我想不出解决办法.感谢您的每一次帮助!如果你需要更多的信息,请告诉我!

Minimal Producable Example:

我的Scaffold:

class ProjectsViewState extends State<ProjectsView>
    with TickerProviderStateMixin {
  late PageViewHolder holder;

  late PageController _controller;
  double fraction = 0.50;

  @override
  void initState() {
    super.initState();
    holder = PageViewHolder(value: 2.0);
    _controller = PageController(initialPage: 2, viewportFraction: fraction);
    _controller.addListener(() {
      holder.setValue(_controller.page);
    });
  }

  int currentPage = 2;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: ChangeNotifierProvider<PageViewHolder>.value(
          value: holder,
          child: Flexible(
            child: PageView.builder(
              controller: _controller,
              onPageChanged: (value) {
                setState(() {
                  currentPage = value;
                });
              },
              itemCount: projectsCounter,
              physics: const BouncingScrollPhysics(),
              itemBuilder: (context, index) {
                return ProjectsGalleryView(
                  number: index.toDouble(),
                  fraction: fraction,
                );
              },
            ),
          ),
        ),
      ),
    );
  }
}

而前pageView名:

class ProjectsGalleryView extends StatefulWidget {
  final double number;
  final double fraction;

  const ProjectsGalleryView(
      {super.key, required this.number, required this.fraction});

  @override
  State<ProjectsGalleryView> createState() => _ProjectsGalleryViewState();
}

class _ProjectsGalleryViewState extends State<ProjectsGalleryView>
    with SingleTickerProviderStateMixin {
  @override
  Widget build(BuildContext context) {
    double value = Provider.of<PageViewHolder>(context).value;
    double diff = (widget.number - value);

    //Matrix for Elements
    final Matrix4 pvMatrix = Matrix4.identity()
      ..setEntry(3, 3, 1 / 0.8) // Increasing Scale by 80%
      // ..setEntry(1, 1, widget.fraction) // Changing Scale Along Y Axis
      ..setEntry(3, 0, 0.003 * -diff); // Changing Perspective Along X Axis

    return Transform(
      transform: pvMatrix,
      alignment: FractionalOffset.center,
      child: Column(
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 0),
            child: SizedBox(
              height: 200,
              width: 200,
              child: Container(
                decoration: BoxDecoration(
                  color: Colors.redAccent,
                  borderRadius: BorderRadius.circular(10),
                ),
              ),
            ),
          ),
          if (diff <= 1.0 && diff >= -1.0) ...[
            AnimatedOpacity(
              duration: const Duration(milliseconds: 100),
              opacity: 1 - diff.abs(),
              child: const Padding(
                padding: EdgeInsets.symmetric(
                  horizontal: 15,
                  vertical: 20,
                ),
                child: Text(
                  'A Text with animated opacity',
                ),
              ),
            ),
          ]
        ],
      ),
    );
  }

推荐答案

好的,如果你想让卷轴在左边也平滑的话.你只需任意设置LARGE NUMBER作为起点,就会感觉到INFINITE(像9万亿这样的大数字).然而,它不会无限期地滚动.

  1. 设置某个较大的数字(例如:const largeInt = 9223372036854;)
  2. 修改你的initState,如下所示

@override
void initState() {
  super.initState();
  holder = PageViewHolder(value: largeInt.toDouble());
  _controller = PageController(
    initialPage: largeInt,
    viewportFraction: fraction,
  );
  _controller.addListener(() {
    holder.setValue(_controller.page);
  });
}

ProjectView人的完整代码

const largeInt = 9223372036854;

class ProjectsView extends StatefulWidget {
  const ProjectsView({super.key});

  @override
  ProjectsViewState createState() => ProjectsViewState();
}

class ProjectsViewState extends State<ProjectsView>
    with TickerProviderStateMixin {
  late PageViewHolder holder;

  late PageController _controller;
  double fraction = 0.50;

  @override
  void initState() {
    super.initState();
    holder = PageViewHolder(value: largeInt.toDouble());
    _controller = PageController(
      initialPage: largeInt,
      viewportFraction: fraction,
    );
    _controller.addListener(() {
      holder.setValue(_controller.page);
    });
  }

  int _currentPage = 2;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: ChangeNotifierProvider<PageViewHolder>.value(
            value: holder,
            child: Column(
              children: [
                Flexible(
                  child: PageView.builder(
                    controller: _controller,
                    onPageChanged: (value) {
                      setState(() => _currentPage = value);
                    },
                    physics: const BouncingScrollPhysics(),
                    itemBuilder: (context, index) {
                      return ProjectsGalleryView(
                        number: index.toDouble(),
                        fraction: fraction,
                      );
                    },
                  ),
                ),
              ],
            )),
      ),
    );
  }
}

//上一次回答

这不是一个完美的解决方案,但要在left side as well上无限滚动,在_controller.addListener内加jumpToPage

首先,不要在Pageview.builder中包含itemCount或将其设置为null.

但是,即使将itemCount设置为null,它仍会在index0时结束.

因此,在初始化PageController之后的initState中添加.

_controller.addListener(() {
  holder.setValue(_controller.page);
  final page = _controller.page;
  if (page == null) return;
  if (page < 2.01 && page > 1.99) {
    _controller.jumpToPage(10);
  }
});

通过在_controller.page介于1.99和2.01之间时添加_controller.jumpToPage(10),_pageController将再次将页面设置为10.

我把这个加到_controller.addListener中的原因是,如果你把它放在onPageChanged中,它会卡顿得很厉害,因为返回的valueint.

然而,即使我使用了Double来将影响降至最低,但当滚动速度真的很快时,它仍然会有一点卡顿,如果它非常快,它有可能无法工作.然而,这将始终适用于正常的逐页滚动.

你的ProjectView Widget的完整代码.

class ProjectsView extends StatefulWidget {
  const ProjectsView({super.key});

  @override
  ProjectsViewState createState() => ProjectsViewState();
}

class ProjectsViewState extends State<ProjectsView>
    with TickerProviderStateMixin {
  late PageViewHolder holder;

  late PageController _controller;
  double fraction = 0.50;

  @override
  void initState() {
    super.initState();
    holder = PageViewHolder(value: 2.0);
    _controller = PageController(initialPage: 2, viewportFraction: fraction);
    _controller.addListener(() {
      holder.setValue(_controller.page);
      final page = _controller.page;
      if (page == null) return;
      if (page < 2.01 && page > 1.99) {
        _controller.jumpToPage(10);
      }
    });
  }

  int currentPage = 2;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: ChangeNotifierProvider<PageViewHolder>.value(
          value: holder,
          child: Flexible(
            child: PageView.builder(
              controller: _controller,
              onPageChanged: (value) {
                setState(() => currentPage = value);
              },
              physics: const BouncingScrollPhysics(),
              itemBuilder: (context, index) {
                return ProjectsGalleryView(
                  number: index.toDouble(),
                  fraction: fraction,
                );
              },
            ),
          ),
        ),
      ),
    );
  }
}

Flutter相关问答推荐

ListTile未正确显示在flutter中

Flutter版本3.19.2需要更新版本的Kotlin Gradle插件./android/build.gradle:ext.kotlin_version = latest-version>'

使用ThemeProvider不在亮模式和暗模式之间切换

点击表情符号按钮后,Flutter 文本域文本编辑控制器将文本恢复为原始值

如何使用Dio/Ffltter(前端)和amp;Go(后端)向API发送正确的请求

Firebase存储不显示在Flutter 中链接的图像

Flutter 数独网格

BaseInputfield和Textfield有什么不同?

如何画三角形的圆角?

运行调试flutter应用程序时出错:B/BL超出范围(最大+/-128MB)到'';

如何使用 Material3 创建带有高度的完美白色提升按钮?

Flutter firebase_auth 和 firebase_core 依赖错误

是否可以在 flutter 应用程序中使用 jetpack compose?

在 Flutter 中读取 Firebase 数据库数据时遇到问题

访问 AsyncSnapshot 中的嵌套属性

改变步进器的线条 colored颜色 Flutter

如何在 Flutter 中将 ScaffoldMessenger 中的 Snackbar 显示为 Widget?

Flutter:如何将列表转换为字符串?

如何在Flutter 中制作自定义微调器?

如何从 Flutter 中的列表中提取 JSON?