Flutter - PageController 错误:“页面值仅在建立内容维度后才可用。”

Mah*_*ala 6 flutter

我正在尝试为 PageView 内的一些小部件设置动画,并创建一个自定义 AnimatedWidget,它使用 PageView 也使用的 PageController。这个想法是当用户滑动幻灯片时将一些文本动画化。下面的代码将在第一次渲染时抛出错误,一旦我开始向左/向右滑动,一切正常,但最初出现错误的红屏。我试图通过检查controller.hasClients来防御,但控制器中已经有1个页面,并且错误来自PageView页面获取器中的断言。\n是否有任何其他道具我可以检查以在第一次渲染后延迟动画?

\n\n
import 'dart:math' as math;\n\nimport 'package:flutter/cupertino.dart';\nimport 'package:flutter/material.dart';\n\nclass MySlider extends StatelessWidget {\n  final _controller = new PageController();\n\n  final List<String> _pages = [\n    'Create your football profile',\n    'Your team, your players, your line-up',\n    'Track the stats that matter and share with others'\n  ];\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      body: Stack(\n        children: [\n          PageView.builder(\n            controller: _controller,\n            itemBuilder: (_, index) => Slide(\n              controller: _controller,\n              position: index,\n              heading: _pages[index],\n            ),\n            itemCount: _pages.length,\n            physics: AlwaysScrollableScrollPhysics(),\n          ),\n        ]\n      )\n    );\n  }\n}\n\nclass Slide extends AnimatedWidget {\n\n  final PageController controller;\n  final String heading;\n  final int position;\n\n  Slide({\n    this.controller,\n    this.heading,\n    this.position\n  }) : super(listenable: controller);\n\n  @override\n  Widget build(BuildContext context) {\n\n    final screenHeight = MediaQuery.of(context).size.height;\n    final textYOffset = controller.hasClients\n        ? screenHeight * (controller.page - position)\n        : 0;\n\n    final opacity = controller.hasClients\n        ? 1.0 - math.max(0, controller.page - position)\n        : 1.0;\n\n    return Stack(\n        alignment: Alignment.topCenter,\n        children: [\n          Positioned(\n              bottom: 120,\n              left: 16,\n              right: 16,\n              child: Transform.translate(\n                  offset: Offset(0, -textYOffset),\n                  child: Opacity(\n                      opacity: opacity,\n                      child: Text(heading)\n                  ),\n              ),\n          )\n        ],\n    );\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

控制台异常:

\n\n
\n

\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90 捕获异常通过小部件库 \xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\ x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\ xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\ x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\ x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\ xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90

\n\n

构建 Slide(animation:

\n\n

PageController#c35ec(一个客户端,偏移量 0.0),脏,依赖项:[MediaQuery],状态:_AnimatedState#05ff4):

\n\n

页面值仅在建立内容维度后才可用。\n 'package:flutter/src/widgets/page_view.dart':

\n\n

断言失败:第 373 行 pos 7:'pixels == null || (minScrollExtent != null &&maxScrollExtent != null)'

\n
\n\n

minScrollExtent此时 0.0 与maxScrollExtent

\n

Joã*_*res 7

考虑到您实现幻灯片的方式以及您收到的关于内容尺寸不可用的错误是可能的,但我认为很难看,解决方案是在尝试使用控制器之前检查尺寸是否可用:

if(controller.position.haveDimensions){
  final screenHeight = MediaQuery.of(context).size.height;
  final textYOffset = controller.hasClients
      ? screenHeight * (controller.page - position)
      : 0;

  final opacity = controller.hasClients
      ? 1.0 - math.max(0, controller.page - position)
      : 1.0;

  return Stack(
    alignment: Alignment.topCenter,
    children: [
      Positioned(
        bottom: 120,
        left: 16,
        right: 16,
        child: Transform.translate(
          offset: Offset(0, -textYOffset),
          child: Opacity(
              opacity: opacity,
              child: Text(heading)
          ),
        ),
      )
    ],
  );
} else {
  return SizedBox();
}
Run Code Online (Sandbox Code Playgroud)

尽管“修复”了显示的错误,但无论我如何更改,最后一页上仍然有错误。您想要的动画可能有更好的实现,但我还没有弄清楚。