Флаттер: как я могу исправить ошибку анимации контроллера страницы - PullRequest
0 голосов
/ 22 февраля 2020

У меня есть страница, содержащая слайдер просмотра страниц с контроллером страниц, и я получаю эту ошибку

[ОШИБКА: flutter / lib / ui / ui_dart_state. cc (157)] Необработанное исключение: Поиск до предка деактивированного виджета небезопасно. E / flutter (7013): в этот момент состояние дерева элементов виджета больше не является стабильным. E / flutter (7013): Чтобы безопасно ссылаться на предка виджета в его методе dispose (), сохраните ссылку на предка, вызвав функцию вызываемого метода зависимости (-ов) InOreditedWidgetOfExactType () в методе didChangeDependencies () виджета.

i я пытаюсь ее решить, но я не могу и я не знаю причину этой ошибки, это мой код, который я использую

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 Ответ

0 голосов
/ 24 февраля 2020

Вы можете скопировать и вставить полный код ниже
Значение MediaQuery.of(context).size.width не готово в initState()
Вы можете использовать WidgetsBinding.instance.addPostFrameCallback
фрагмент кода

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

рабочая демоверсия

enter image description here

выход

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"))),
        ],
      ),
    );
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...