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