Flutter:如何修复页面控制器动画错误

Posted

技术标签:

【中文标题】Flutter:如何修复页面控制器动画错误【英文标题】:Flutter: How I can fix page controller animation error 【发布时间】:2020-06-06 21:31:30 【问题描述】:

我有一个包含页面视图滑块和页面控制器的页面,我收到此错误:

[错误:flutter/lib/ui/ui_dart_state.cc(157)] 未处理的异常:

查找已停用小部件的祖先是不安全的。 E/颤动​​(

7013):此时widget的元素树的状态为no

更稳定。 E/flutter (7013):安全地引用一个小部件的

在其 dispose() 方法中,保存对祖先的引用

在小部件中调用dependOnInheritedWidgetOfExactType()

didChangeDependencies() 方法。

我正在尝试解决它,但我不能,我不知道这个错误的原因。 这是我使用的代码:

var pageController = PageController(initialPage: 0);
  var pageViewModelData = List<PageViewData>();

  Timer sliderTimer;
  var currentShowIndex = 0;

  @override
  void initState() 
    pageViewModelData.add(PageViewData(
      titleText: 'Cape Town',
      subText: 'Extraordinary five-star\noutdoor activites',
      assetsImage: 'assets/images/explore_2.jpg',
    ));
    pageViewModelData.add(PageViewData(
      titleText: 'Find best deals',
      subText: 'Extraordinary five-star\noutdoor activites',
      assetsImage: 'assets/images/explore_1.jpg',
    ));
    pageViewModelData.add(PageViewData(
      
      titleText: 'Find best deals',
      subText: 'Extraordinary five-star\noutdoor activites',
      assetsImage: 'assets/images/explore_3.jpg',
    ));

    sliderTimer = Timer.periodic(Duration(seconds: 4), (timer) 
      if (currentShowIndex == 0) 
        pageController.animateTo(MediaQuery.of(context).size.width, duration: Duration(seconds: 1), curve: Curves.fastOutSlowIn);
       else if (currentShowIndex == 1) 
        pageController.animateTo(MediaQuery.of(context).size.width * 2, duration: Duration(seconds: 1), curve: Curves.fastOutSlowIn);
       else if (currentShowIndex == 2) 
        pageController.animateTo(0, duration: Duration(seconds: 1), curve: Curves.fastOutSlowIn);
      
    );
    super.initState();
  

  @override
  void dispose() 
    sliderTimer?.cancel();
    super.dispose();
  

我从这一行开始得到错误:

MediaQuery.of(context).size.width

谁能告诉我这个问题的原因!谢谢

【问题讨论】:

【参考方案1】:

您可以在下面复制粘贴运行完整代码MediaQuery.of(context).size.width 的值在 initState() 中未准备好 您可以使用WidgetsBinding.instance.addPostFrameCallback 代码sn-p

WidgetsBinding.instance.addPostFrameCallback((_) 
      print('width $MediaQuery.of(context).size.width');
      sliderTimer = Timer.periodic(Duration(seconds: 4), (timer) 
        if (currentShowIndex == 0) 
          pageController.animateTo(MediaQuery.of(context).size.width, duration: Duration(seconds: 1), curve: Curves.fastOutSlowIn);
         else if (currentShowIndex == 1) 
          pageController.animateTo(MediaQuery.of(context).size.width * 2, duration: Duration(seconds: 1), curve: Curves.fastOutSlowIn);
         else if (currentShowIndex == 2) 
          pageController.animateTo(0, duration: Duration(seconds: 1), curve: Curves.fastOutSlowIn);
        
      );
    );

工作演示

输出

I/flutter ( 1876): width 411.42857142857144

完整代码

import 'dart:io';
import 'dart:async';
import 'package:flutter/material.dart';

void main() 
  runApp(new MaterialApp(
    title: 'Flutter Tutorial',
    home: new AnimatedIconExample(),
  ));


class AnimatedIconExample extends StatefulWidget 
  @override
  _AnimatedIconExampleState createState() => _AnimatedIconExampleState();


class _AnimatedIconExampleState extends State<AnimatedIconExample>
    with SingleTickerProviderStateMixin 
  PageController pageController = PageController();
  AnimationController controller;
  Timer sliderTimer;
  var currentShowIndex = 0;

  @override
  void initState() 
    super.initState();
    controller =
        AnimationController(vsync: this, duration: Duration(seconds: 1));

    WidgetsBinding.instance.addPostFrameCallback((_) 
      print('width $MediaQuery.of(context).size.width');
      sliderTimer = Timer.periodic(Duration(seconds: 4), (timer) 
        if (currentShowIndex == 0) 
          pageController.animateTo(MediaQuery.of(context).size.width, duration: Duration(seconds: 1), curve: Curves.fastOutSlowIn);
         else if (currentShowIndex == 1) 
          pageController.animateTo(MediaQuery.of(context).size.width * 2, duration: Duration(seconds: 1), curve: Curves.fastOutSlowIn);
         else if (currentShowIndex == 2) 
          pageController.animateTo(0, duration: Duration(seconds: 1), curve: Curves.fastOutSlowIn);
        
      );
    );


  


  @override
  void dispose() 
    controller?.dispose();
    super.dispose();
  

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
          leading: GestureDetector(
            child: Center(
              child: AnimatedIcon(
                  icon: AnimatedIcons.menu_close, progress: controller),
            ),
            onTap: () 
              controller.reverse();
              pageController.animateToPage(0,
                  duration: Duration(seconds: 1), curve: Curves.linear);
            ,
          ),
          title: Text("Animated PageView Controller")),
      body: PageView(
        controller: pageController,
        scrollDirection: Axis.vertical,
        children: <Widget>[
          buildPage0(),
          Container(color: Colors.green),
          Container(color: Colors.blue),
          Container(color: Colors.yellow),
          Container(color: Colors.pink),
        ],
      ),
    );
  

  show(int page) 
    controller.forward();
    pageController.animateToPage(page,
        duration: Duration(seconds: 1), curve: Curves.linear);
  

  Container buildPage0() 
    return Container(
      color: Colors.white,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          ListTile(onTap: () => show(1), title: Center(child: Text("Green"))),
          ListTile(onTap: () => show(2), title: Center(child: Text("Blue"))),
          ListTile(onTap: () => show(3), title: Center(child: Text("Yellow"))),
          ListTile(onTap: () => show(4), title: Center(child: Text("Pink"))),
        ],
      ),
    );
  

【讨论】:

以上是关于Flutter:如何修复页面控制器动画错误的主要内容,如果未能解决你的问题,请参考以下文章

Flutter:动画控制器数组

如何“取消处置”动画控制器以供重用?

如何修复“minified:aq<void>”flutter web 错误

如何修复 Apple Watch 页面控制器中缺少的界面控制器?

当应用程序在本地运行时如何修复 PHP 上的重定向错误

UINavigationController 在自定义过渡动画后忘记如何旋转子控制器