【问题标题】:Flutter - PageController error: `Page value is only available after content dimensions are established.`Flutter - PageController 错误:`页面值仅在建立内容维度后可用。`
【发布时间】:2020-05-04 02:19:49
【问题描述】:

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

import 'dart:math' as math;

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

class MySlider extends StatelessWidget {
  final _controller = new PageController();

  final List<String> _pages = [
    'Create your football profile',
    'Your team, your players, your line-up',
    'Track the stats that matter and share with others'
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          PageView.builder(
            controller: _controller,
            itemBuilder: (_, index) => Slide(
              controller: _controller,
              position: index,
              heading: _pages[index],
            ),
            itemCount: _pages.length,
            physics: AlwaysScrollableScrollPhysics(),
          ),
        ]
      )
    );
  }
}

class Slide extends AnimatedWidget {

  final PageController controller;
  final String heading;
  final int position;

  Slide({
    this.controller,
    this.heading,
    this.position
  }) : super(listenable: controller);

  @override
  Widget build(BuildContext context) {

    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)
                  ),
              ),
          )
        ],
    );
  }
}

控制台中的异常:

════════小部件库捕获的异常═════════════════════════════════════ ═══════════

在构建幻灯片(动画:

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

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

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

minScrollExtent 此时为 0.0,与 maxScrollExtent 相同

【问题讨论】:

    标签: flutter


    【解决方案1】:

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

    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();
    }
    

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

    【讨论】:

    • 嗨 João,感谢您回答我的问题,您的解决方案运行良好。我没有看到滑动到最后一页的任何错误,如果我无法正确计算,我总是呈现相同的小部件树并使用后备动画值。您对实现此类动画的更好方法有什么建议吗?我可以阅读一些提示或链接?我是 Flutter 的新手,您的评论表明这可能不是一个好方法。
    • @Mahakala 目前没有,抱歉。当我有时间时,我会尝试它。如果我的回答解决了您的问题,请记得将其标记为正确,以帮助未来的用户。祝你的应用好运!
    • 很高兴能帮上忙。祝你的应用好运!
    猜你喜欢
    • 1970-01-01
    • 2021-11-19
    • 2021-01-01
    • 2013-01-27
    • 2021-04-04
    • 1970-01-01
    • 2017-11-28
    • 2021-11-08
    • 1970-01-01
    相关资源
    最近更新 更多