Flutter 颤振小部件中的didChangeDependencies钩子包含类的不准确数据

Flutter 颤振小部件中的didChangeDependencies钩子包含类的不准确数据,flutter,dart,flutter-layout,flutter-dependencies,Flutter,Dart,Flutter Layout,Flutter Dependencies,在我下面的代码中,我在Flutter中与LifeCyrles搏斗,我可以在Provider中更新我的状态,显然,只有在didChangeDependencieshook或模板小部件中(通过按钮上挂起的事件等等) 好的,我不介意只有didChangeDependencies钩子对我有效,但当我在前面提到的钩子中的逻辑依赖于一些类属性时,我对类数据的准确性有问题。 我在后面一步得到数据(因为它是在buildhook之前调用的) 我无法在构建钩子中运行此逻辑,因为它包含一个更改提供程序中状态的请求。如

在我下面的代码中,我在Flutter中与LifeCyrles搏斗,我可以在Provider中更新我的状态,显然,只有在
didChangeDependencies
hook或模板小部件中(通过按钮上挂起的事件等等)

好的,我不介意只有didChangeDependencies钩子对我有效,但当我在前面提到的钩子中的逻辑依赖于一些类属性时,我对类数据的准确性有问题。 我在后面一步得到数据(因为它是在
build
hook之前调用的)

我无法在构建钩子中运行此逻辑,因为它包含一个更改提供程序中状态的请求。如果我尝试更改那里的状态,则会出现以下错误之一:

setState()或markNeedsBuild()在生成过程中被调用。

还是这个

对null调用了setter'lastPage='。
收件人:空
尝试呼叫:lastPage=true

我想做什么:我有一个包装器小部件,它包含另外三个小部件:页脚、页眉和页面查看器。 当我到达最后一页时,我需要通知我的包装器小部件,以便它相应地做出反应并隐藏页眉和页脚

我将非常感谢您的帮助

重点代码:

这就是问题所在,也是必须解决的问题

在第一轮集结时只调用一次,就这样。 我在这里缺少一个角度挂钩
AfterViewInit
。这里很方便

或在VueJS中装入


如果你想了解整个情况,这就是我代码的其余部分。 如果您对架构、结构或其他方面有任何建议,欢迎您提出。这是高度赞赏,因为我是新的飞

main.dart

import 'package:flutter/material.dart';
import 'package:ui_flutter/routing.dart';
import 'package:provider/provider.dart';
import 'screens/welcome/welcome_bloc.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => WelcomeBloc()),
      ],
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        initialRoute: '/welcome',
        onGenerateRoute: RouteGenerator.generateRoute,
      ),
    );
  }
}

欢迎光临。飞镖(我的包装纸)

footer.dart(这就是我对代码最底层数据的问题所在-\u detectLastPage方法)

导入“包装:颤振/材料.省道”;
导入“包:provider/provider.dart”;
导入“包:ui_flatter/screens/welcome/welcome_bloc.dart”;
导入“package:flatter/scheduler.dart”;
类页脚扩展StatefulWidget{
最后一步;
最后步骤;
最终颜色-活性色;
最终颜色;
最后期限;
最终函数onFinal;
最终功能启动;
页脚({
这个.activeColor,
这是彩色的,
这一步,,
这一步,,
这个时间,,
最后,
这个.onStart,
}) {}
@凌驾
_FooterState createState()=>\u FooterState();
}
类_FooterState扩展了状态{
最终双半径=10.0;
最终双倍距离=4.0;
集装箱步进机;
货柜码头;
布尔最后一页;
WelcomeBloc(WelcomeBloc);;
@凌驾
void didChangeDependencies(){
super.didChangeDependencies();
最终WelcomeBloc _welcome=Provider.of(上下文);
_欢迎光临;
这个;
}
@凌驾
小部件构建(构建上下文){
这个;
这个;
返回容器(
对齐:对齐.bottomCenter,
填充:边缘组。对称(垂直:30.0,水平:30.0),
孩子:排(
mainAxisAlignment:mainAxisAlignment.spaceBetween,
crossAxisAlignment:crossAxisAlignment.center,
儿童:[
这是步进机,
这个,下一个塔罗,
],
),
);
}
_makeCirle(activeColor、inactiveColor、position、currentStep){
currentStep=currentStep==null?0:currentStep-1;
颜色颜色=(位置==当前步骤)?activeColor:inactiveColor;
返回容器(
高度:这个半径,
宽度:这个半径,
边距:仅限边集(左:this.distance,右:this.distance),
装饰:盒子装饰(
颜色:颜色,
边框:边框。全部(颜色:activeColor,宽度:2.0),
边界半径:边界半径。圆形(50.0)),
);
}
_makeStepper(){
列表圆=列表();
对于(var i=0;i

提前感谢

我也不熟悉flifter,但我已经了解了一些帮助我构建一些应用程序的架构模式

我是这样做的:

创建一个
提供程序
,它在运行时为您保存数据。(在您的情况下,它可以是一个
Bloc
)。坚持一种体系结构,不要试图把一个
SchedulerBinding.instance
        .addPostFrameCallback((_) => this._detectLastPage());
import 'package:flutter/material.dart';
import 'package:ui_flutter/routing.dart';
import 'package:provider/provider.dart';
import 'screens/welcome/welcome_bloc.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => WelcomeBloc()),
      ],
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        initialRoute: '/welcome',
        onGenerateRoute: RouteGenerator.generateRoute,
      ),
    );
  }
}

import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:provider/provider.dart';
import 'package:ui_flutter/screens/welcome/welcome_bloc.dart';
import './footer.dart';
import './viewWrapper.dart';
import './header.dart';
// import 'package:ui_flutter/routing.dart';

class Welcome extends StatefulWidget {
  @override
  _WelcomeState createState() => _WelcomeState();
}

class _WelcomeState extends State<Welcome> {
  WelcomeBloc _welcomeBloc;

  @override
  Widget build(BuildContext context) {
    final WelcomeBloc _welcome = Provider.of<WelcomeBloc>(context);
    this._welcomeBloc = _welcome;
    print('Welcome: _welcome.currentPage - ${this._welcomeBloc.lastPage}');

    return Scaffold(
      body: SafeArea(
        child: Stack(
          children: <Widget>[
            ViewerWrapper(),
            Footer(
              currentStep: _welcomeBloc.currentPage,
              totalSteps: 3,
              activeColor: Colors.grey[800],
              inactiveColor: Colors.grey[100],
            ),
            WelcomeHeader,
          ],
        ),
      ),
    );
  }
}
import 'package:flutter/material.dart';

class WelcomeBloc extends ChangeNotifier {
  PageController _controller = PageController();
  int _currentPage;
  bool _lastPage = false;

  bool get lastPage => _lastPage;

  set lastPage(bool value) {
    _lastPage = value;
    notifyListeners();
  }

  int get currentPage => _currentPage;

  set currentPage(int value) {
    _currentPage = value;
    notifyListeners();
  }

  get controller => _controller;

  nextPage(Duration duration, Curves curve) {
    controller.nextPage(duration: duration, curve: curve);
  }
}
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:ui_flutter/screens/welcome/welcome_bloc.dart';
import 'package:flutter/scheduler.dart';

class Footer extends StatefulWidget {
  final int currentStep;
  final int totalSteps;
  final Color activeColor;
  final Color inactiveColor;
  final Duration duration;
  final Function onFinal;
  final Function onStart;

  Footer({
    this.activeColor,
    this.inactiveColor,
    this.currentStep,
    this.totalSteps,
    this.duration,
    this.onFinal,
    this.onStart,
  }) {}

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

class _FooterState extends State<Footer> {
  final double radius = 10.0;
  final double distance = 4.0;
  Container stepper;
  Container nextArrow;
  bool lastPage;
  WelcomeBloc _welcomeBloc;

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();

    final WelcomeBloc _welcome = Provider.of<WelcomeBloc>(context);
    _welcomeBloc = _welcome;
    this._detectLastPage();
  }

  @override
  Widget build(BuildContext context) {
    this._makeStepper();
    this._makeNextArrow();

    return Container(
      alignment: Alignment.bottomCenter,
      padding: EdgeInsets.symmetric(vertical: 30.0, horizontal: 30.0),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: <Widget>[
          this.stepper,
          this.nextArrow,
        ],
      ),
    );
  }

  _makeCirle(activeColor, inactiveColor, position, currentStep) {
    currentStep = currentStep == null ? 0 : currentStep - 1;
    Color color = (position == currentStep) ? activeColor : inactiveColor;

    return Container(
      height: this.radius,
      width: this.radius,
      margin: EdgeInsets.only(left: this.distance, right: this.distance),
      decoration: BoxDecoration(
          color: color,
          border: Border.all(color: activeColor, width: 2.0),
          borderRadius: BorderRadius.circular(50.0)),
    );
  }

  _makeStepper() {
    List<Container> circles = List();

    for (var i = 0; i < widget.totalSteps; i++) {
      circles.add(
        _makeCirle(this.widget.activeColor, this.widget.inactiveColor, i,
            this.widget.currentStep),
      );
    }

    this.stepper = Container(
      child: Row(
        children: circles,
      ),
    );
  }

  _makeNextArrow() {
    this.nextArrow = Container(
      child: Padding(
        padding: const EdgeInsets.only(right: 8.0),
        child: GestureDetector(
            onTap: () {
              _welcomeBloc.controller.nextPage(
                duration: this.widget.duration ?? Duration(milliseconds: 500),
                curve: Curves.easeInOut,
              );
            },
            child: Icon(
              Icons.arrow_forward,
            )),
      ),
    );
  }

  _onLastPage() {
    if (this.widget.onFinal != null) {
      this.widget.onFinal();
    }
  }

  _onFirstPage() {
    if (this.widget.onStart != null) {
      this.widget.onStart();
    }
  }

  _detectLastPage() {
    // Here I've got inaccurate data 

    int currentPage =
        this.widget.currentStep == null ? 1 : this.widget.currentStep;

    if (currentPage == 1 && this.widget.currentStep == null) {
      this._onFirstPage();
    } else if (currentPage == this.widget.totalSteps) {
      print('lastPage detected');
      setState(() {
        this.lastPage = true;
      });
      _welcomeBloc.lastPage = true;
      this._onLastPage();
    } else {
      setState(() {
        this.lastPage = false;
      });
      _welcomeBloc.lastPage = false;
    }
  }
}
SchedulerBinding.instance
        .addPostFrameCallback((_) => this._detectLastPage());
Future.microtask(() => this._detectLastPage());