点击showModalBottomSheet触发空检查运算符错误,求代码排查
问题定位与修复:点击
showModalBottomSheet触发空指针错误 错误信息
点击showModalBottomSheet时抛出以下错误:
Null Check operator used on a null value
错误堆栈:
#0 _ProductContentFirstState._getAttrWidget.<anonymous closure (package:flutter_jdshop/pages/ProductContent/ProductContentFirst.dart:64:54)
错误原因分析
_getAttrItemWidget方法未返回列表:该方法内部创建了attrItemList但无返回语句,默认返回null,后续代码用!强制解包null触发空指针。_getAttrWidget方法未返回列表:同理,该方法创建attrList后未返回,默认返回null,在Column的children参数中强制解包null引发错误。- 未处理
attrItem.list为空的情况:Attr类中的list是可空类型,直接调用forEach会在list为null时崩溃。 - 初始数据未做空处理:
initState中直接用!解包_productContent!.attr!,若初始数据为空会提前崩溃。
修复方案
1. 修正_getAttrItemWidget方法
添加返回语句,同时处理list为空的情况:
List<Widget>? _getAttrItemWidget(Attr attrItem) { List<Widget> attrItemList = []; // 用?.避免list为null时调用forEach崩溃 attrItem.list?.forEach((item) { attrItemList.add(Container( margin: EdgeInsets.all(5), child: Chip( label: Text("${item}"), padding: EdgeInsets.all(10), ), )); print(item); }); return attrItemList; }
2. 修正_getAttrWidget方法
添加返回语句,替换强制解包为安全的空合并运算符:
List<Widget>? _getAttrWidget() { List<Widget> attrList = []; this._attr.forEach((Attr attrItem) { attrList.add(Wrap( children: [ Container( width: ScreenAdapter.width(80.0), child: Padding( padding: EdgeInsets.only(top: ScreenAdapter.height(30.0)), child: Text( "${attrItem.cate ?? ''}", // 处理cate为空的情况 style: TextStyle( fontWeight: FontWeight.bold, ), ), ), ), Container( width: ScreenAdapter.width(600.0), child: Wrap( // 用??兜底空列表,避免null children: _getAttrItemWidget(attrItem) ?? [], ), ) ], )); print(attrItem.cate); }); return attrList; }
3. 修正底部弹窗中的强制解包
将!替换为空合并运算符,避免null:
Column( children: _getAttrWidget() ?? [], )
4. 优化初始数据处理
在initState中添加空判断,避免初始数据为空时崩溃:
@override void initState() { super.initState(); _productContent = widget._productContentList[0]; // 用??兜底空列表,处理attr为空的情况 this._attr = this._productContent?.attr ?? []; }
5. 修正无效代码
将onTap中的无效代码false;替换为空代码块:
GestureDetector( onTap: () {}, // ...其余代码不变 )
完整修复后的关键代码片段
class _ProductContentFirstState extends State<ProductContentFirst> { ProductContentItem? _productContent; List<Attr> _attr = []; // 修正类型为List<Attr> @override void initState() { super.initState(); _productContent = widget._productContentList[0]; this._attr = this._productContent?.attr ?? []; } List<Widget>? _getAttrItemWidget(Attr attrItem) { List<Widget> attrItemList = []; attrItem.list?.forEach((item) { attrItemList.add(Container( margin: EdgeInsets.all(5), child: Chip( label: Text("${item}"), padding: EdgeInsets.all(10), ), )); print(item); }); return attrItemList; } List<Widget>? _getAttrWidget() { List<Widget> attrList = []; this._attr.forEach((Attr attrItem) { attrList.add(Wrap( children: [ Container( width: ScreenAdapter.width(80.0), child: Padding( padding: EdgeInsets.only(top: ScreenAdapter.height(30.0)), child: Text( "${attrItem.cate ?? ''}", style: TextStyle( fontWeight: FontWeight.bold, ), ), ), ), Container( width: ScreenAdapter.width(600.0), child: Wrap( children: _getAttrItemWidget(attrItem) ?? [], ), ) ], )); print(attrItem.cate); }); return attrList; } _attrBottomSheet() { showModalBottomSheet( context: context, builder: (context) { return GestureDetector( onTap: () {}, child: Stack( children: [ Container( padding: EdgeInsets.all(10), child: ListView( children: [ Column( children: _getAttrWidget() ?? [], ) ], ), ), Positioned( bottom: 0, width: ScreenAdapter.width(750.0), height: ScreenAdapter.height(100), child: Row( children: [ Expanded( flex: 1, child: Container( child: JdButton( color: Color.fromRGBO(253, 1, 0, 0.9), text: "Add Cart", cb: () { print("Add Cart"); }, ), )), Expanded( flex: 1, child: Container( child: JdButton( color: Color.fromRGBO(255, 165, 0, 0.9), text: "Buy", cb: () { print("Buy"); }, ), )), ], )) ], ), ); }); } // build方法保持不变 }
内容的提问来源于stack exchange,提问作者jordan
相关产品推荐
相关产品推荐

