Flutter中使用ValueListenableBuilder后无法访问widget.homeTween变量
解决ValueListenableBuilder中无法访问State.widget变量的问题
问题说明
将Text组件用ValueListenableBuilder包裹后,访问widget.homeTween时出现报错:
The property 'homeTween' can't be unconditionally accessed because the receiver can be 'null'
相关代码片段:
ValueListenableBuilder<Box<String>>( valueListenable: _localUser.listenable(), builder: (context, box, widget) { return Text( '${getGreetings()!} ${_localUser.get("_firstName")}s', style: TextStyle( color: widget.homeTween!.value as Color, fontSize: 16, fontFamily: 'Nunito Regular', ), ); }, ),
未包裹ValueListenableBuilder时代码运行正常,完整Widget类代码见文末。
问题原因
ValueListenableBuilder的builder函数第三个参数被命名为widget,这和State类中默认的widget属性(指向StatefulWidget实例)重名了。在builder函数内部,widget指代的是builder的可选参数(类型为Widget?,可空),而非State类中的widget(指向AnimatedAppBar实例,包含homeTween等属性),因此直接访问widget.homeTween会因为变量可空而报错。
解决方案
方案1:修改builder参数名避免重名
将builder函数的第三个参数名称改为非widget的命名(比如child),之后即可正常通过widget.homeTween访问StatefulWidget的属性:
ValueListenableBuilder<Box<String>>( valueListenable: _localUser.listenable(), // 修改第三个参数名,避免与State的widget重名 builder: (context, box, child) { return Text( '''${getGreetings()!} ${Namefully(_localUser.get("_firstName").toString())}''', style: TextStyle( color: widget.homeTween!.value as Color, fontSize: 16, fontFamily: 'Nunito Regular', ), ); }, ),
方案2:明确指定访问State的widget属性
如果不想修改参数名,也可以通过this.widget明确指向State类的widget属性,强制区分重名变量:
builder: (context, box, widget) { return Text( '''${getGreetings()!} ${Namefully(_localUser.get("_firstName").toString())}''', style: TextStyle( // 通过this.widget明确访问State的widget实例 color: this.widget.homeTween!.value as Color, fontSize: 16, fontFamily: 'Nunito Regular', ), ); },
完整Widget类代码
// Imports: import 'package:dogbase_app/theme/app_styles.dart'; import 'package:dogbase_app/utilities/helpers/greetings.dart'; import 'package:dogbase_app/utilities/hive/local_user.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gravatar/flutter_gravatar.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:namefully/namefully.dart'; class AnimatedAppBar extends StatefulWidget { const AnimatedAppBar({ Key? key, required this.colorAnimationController, required this.onPressed, required this.colorTween, required this.homeTween, required this.iconTween, required this.drawerTween, required this.workOutTween, required this.loadpage, }) : super(key: key); final AnimationController colorAnimationController; final Animation<dynamic>? colorTween; final Animation<dynamic>? workOutTween; final Animation<dynamic>? homeTween; final Animation<dynamic>? iconTween; final Animation<dynamic>? drawerTween; final VoidCallback onPressed; final Function loadpage; @override State<AnimatedAppBar> createState() => _AnimatedAppBarState(); } class _AnimatedAppBarState extends State<AnimatedAppBar> { late Gravatar? _gravatar; @override void initState() { super.initState(); } final _localUser = LocalUser().getUser(); @override Widget build(BuildContext context) { return SizedBox( height: 65, child: AnimatedBuilder( animation: widget.colorAnimationController, builder: (context, child) => AppBar( toolbarHeight: 65, leading: IconButton( icon: Icon( Icons.dehaze, color: widget.drawerTween!.value as Color, ), onPressed: widget.onPressed, ), backgroundColor: widget.colorTween!.value as Color, elevation: 0, titleSpacing: 0, title: Row( children: <Widget>[ ValueListenableBuilder<Box<String>>( valueListenable: _localUser.listenable(), builder: (context, box, child) { return Text( '''${getGreetings()!} ${Namefully(_localUser.get("_firstName").toString())}''', style: TextStyle( color: widget.homeTween!.value as Color, fontSize: 16, fontFamily: 'Nunito Regular', ), ); }, ), ], ), actions: <Widget>[ Icon( Icons.notifications, color: widget.iconTween!.value as Color, ), Padding( padding: const EdgeInsets.all(10), child: GestureDetector( onTap: () { widget.loadpage(8, accentColor); }, child: CircleAvatar( backgroundColor: whiteColor, radius: 45, child: ClipOval( child: Image.network( _gravatar!.imageUrl(), ), ), ), ), ), ], ), ), ); } }
内容的提问来源于stack exchange,提问作者Almog
相关产品推荐
相关产品推荐

