Flutter中ParentDataWidget使用错误异常求助
Flutter项目「Incorrect use of Parent Data Widget」异常排查解决
问题场景
代码可正常运行,但控制台抛出如下异常:
Incorrect use of Parent Data Widget flutter for details
相关组件代码如下:
主页(HomePage)代码
class HomePage extends StatefulWidget { const HomePage({super.key}); @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { late final stream = FirebaseDatabase.instance.ref('sensor/').onValue; int counter = 0; @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.black, body: SingleChildScrollView( child: Stack( children: [ StreamBuilder( stream: stream, builder: (context, snapshot) { if (snapshot.hasData) { final data = snapshot.data?.snapshot.value as Map?; if (data == null) { return Text('No data'); } final sensorEC = data['EC']; final sensorPH = data['PH']; final sensorRTD = data['RTD']; final humidity = data['humidity']; final temperature = data['temperature']; return Stack( children: [ Container( margin: EdgeInsets.only(top: 70, left: 10), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "SHOWCASE", style: whiteTextStyle.copyWith( fontSize: 20, fontWeight: bold), ), Spacer(), Icon( Icons.account_circle, size: 30, color: Colors.blueGrey, ), ], ), ), Container( margin: EdgeInsets.only( top: 110, left: 10, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( child: Text( "Water Management", style: whiteTextStyle.copyWith(fontSize: 16), ), ), SizedBox( height: 10, ), Container( child: Row( children: [ ParamWaterManagement( nameSensor: 'EC', valueSensor: '$sensorEC', ), ParamWaterManagement( nameSensor: 'PH', valueSensor: '$sensorPH'), ParamWaterManagement( nameSensor: 'RTD', valueSensor: '$sensorRTD'), ], ), ), ], ), ), Container( margin: EdgeInsets.only( top: 200, left: 10, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( child: Text( "Water Climate", style: whiteTextStyle.copyWith(fontSize: 16), ), ), SizedBox( height: 10, ), Container( child: Row( children: [ ParamWaterClimate( nameSensor: 'humidity', valueSensor: '$humidity', ), ParamWaterClimate( nameSensor: 'temperature', valueSensor: '$temperature'), ], ), ), ], ), ), ], ); } if (snapshot.hasError) { print(snapshot.error.toString()); return Text(snapshot.error.toString()); } return Text('....'); }, ), ], ), ), ); } }
Water Management组件代码
class ParamWaterManagement extends StatelessWidget { final String nameSensor; final String valueSensor; ParamWaterManagement({Key? key, required this.nameSensor, required this.valueSensor}); @override Widget build(BuildContext context) { return Container( alignment: Alignment.center, width: 110, height: 55, margin: const EdgeInsets.only( right: 7, ), decoration: BoxDecoration( borderRadius: BorderRadius.circular(5), color: kPrimaryColor, ), child: Padding( padding: const EdgeInsets.all(4.0), child: Expanded( child: Column(children: [ Expanded( child: Text( '$nameSensor (μS/cm)', style: whiteTextStyle.copyWith( fontSize: 12, fontWeight: bold, decoration: TextDecoration.none), ), ), const SizedBox( height: 6, ), Text( '$valueSensor', style: neonBasicStyle.copyWith( fontSize: 17, fontWeight: bold, decoration: TextDecoration.none, ), ) ]), ), ), ); } }
Water Climate组件代码
class ParamWaterClimate extends StatelessWidget { final String nameSensor; final String valueSensor; ParamWaterClimate({Key? key, required this.nameSensor, required this.valueSensor}); @override Widget build(BuildContext context) { return Container( alignment: Alignment.centerLeft, width: 120, height: 55, margin: EdgeInsets.only( right: 7, ), decoration: BoxDecoration( borderRadius: BorderRadius.circular(5), color: kPrimaryColor, ), child: Padding( padding: const EdgeInsets.all(4.0), child: Expanded( child: Column(children: [ Expanded( child: Text( "$nameSensor (μS/cm)", style: whiteTextStyle.copyWith( fontSize: 12, fontWeight: bold, decoration: TextDecoration.none, ), ), ), SizedBox( height: 6, ), Text( '$valueSensor', style: neonBasicStyle.copyWith( fontSize: 17, fontWeight: bold, decoration: TextDecoration.none, ), ) ]), ), ), ); } }
异常原因
Expanded组件仅能作为Row、Column、Flex这类弹性布局容器的直接子组件使用,它的作用是在弹性布局中分配剩余空间。
在你提供的ParamWaterManagement和ParamWaterClimate组件里,Expanded被嵌套在了Padding组件内部,而Padding并非弹性布局容器,这违反了Expanded的使用规则,从而触发了该异常。
修复方案
方案一:调整组件层级,让Expanded成为弹性布局的直接子节点
将Padding与Expanded的层级调换,让Expanded直接作为Column的子节点,Padding包裹内部的Text组件:
修复后的ParamWaterManagement
class ParamWaterManagement extends StatelessWidget { final String nameSensor; final String valueSensor; ParamWaterManagement({Key? key, required this.nameSensor, required this.valueSensor}); @override Widget build(BuildContext context) { return Container( alignment: Alignment.center, width: 110, height: 55, margin: const EdgeInsets.only(right: 7), decoration: BoxDecoration( borderRadius: BorderRadius.circular(5), color: kPrimaryColor, ), child: Column( children: [ Expanded( child: Padding( padding: const EdgeInsets.all(4.0), child: Text( '$nameSensor (μS/cm)', style: whiteTextStyle.copyWith( fontSize: 12, fontWeight: bold, decoration: TextDecoration.none), ), ), ), const SizedBox(height: 6), Padding( padding: const EdgeInsets.all(4.0), child: Text( '$valueSensor', style: neonBasicStyle.copyWith( fontSize: 17, fontWeight: bold, decoration: TextDecoration.none, ), ), ) ], ), ); } }
修复后的ParamWaterClimate
class ParamWaterClimate extends StatelessWidget { final String nameSensor; final String valueSensor; ParamWaterClimate({Key? key, required this.nameSensor, required this.valueSensor}); @override Widget build(BuildContext context) { return Container( alignment: Alignment.centerLeft, width: 120, height: 55, margin: EdgeInsets.only(right: 7), decoration: BoxDecoration( borderRadius: BorderRadius.circular(5), color: kPrimaryColor, ), child: Column( children: [ Expanded( child: Padding( padding: const EdgeInsets.all(4.0), child: Text( "$nameSensor (μS/cm)", style: whiteTextStyle.copyWith( fontSize: 12, fontWeight: bold, decoration: TextDecoration.none, ), ), ), ), SizedBox(height: 6), Padding( padding: const EdgeInsets.all(4.0), child: Text( '$valueSensor', style: neonBasicStyle.copyWith( fontSize: 17, fontWeight: bold, decoration: TextDecoration.none, ), ), ) ], ), ); } }
方案二:移除Expanded,利用Column的主轴对齐分配空间
由于外层Container已经固定了宽高,可以直接将padding移到外层Container,然后通过Column的mainAxisAlignment属性分配内部空间,这样无需使用Expanded,代码更简洁:
简化后的ParamWaterManagement
class ParamWaterManagement extends StatelessWidget { final String nameSensor; final String valueSensor; ParamWaterManagement({Key? key, required this.nameSensor, required this.valueSensor}); @override Widget build(BuildContext context) { return Container( alignment: Alignment.center, width: 110, height: 55, margin: const EdgeInsets.only(right: 7), padding: const EdgeInsets.all(4.0), decoration: BoxDecoration( borderRadius: BorderRadius.circular(5), color: kPrimaryColor, ), child: Column( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Text( '$nameSensor (μS/cm)', style: whiteTextStyle.copyWith( fontSize: 12, fontWeight: bold, decoration: TextDecoration.none), ), Text( '$valueSensor', style: neonBasicStyle.copyWith( fontSize: 17, fontWeight: bold, decoration: TextDecoration.none, ), ) ], ), ); } }
简化后的ParamWaterClimate
class ParamWaterClimate extends StatelessWidget { final String nameSensor; final String valueSensor; ParamWaterClimate({Key? key, required this.nameSensor, required this.valueSensor}); @override Widget build(BuildContext context) { return Container( alignment: Alignment.centerLeft, width: 120, height: 55, margin: EdgeInsets.only(right: 7), padding: const EdgeInsets.all(4.0), decoration: BoxDecoration( borderRadius: BorderRadius.circular(5), color: kPrimaryColor, ), child: Column( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Text( "$nameSensor (μS/cm)", style: whiteTextStyle.copyWith( fontSize: 12, fontWeight: bold, decoration: TextDecoration.none, ), ), Text( '$valueSensor', style: neonBasicStyle.copyWith( fontSize: 17, fontWeight: bold, decoration: TextDecoration.none, ), ) ], ), ); } }
内容的提问来源于stack exchange,提问作者Erick Mahardika
相关产品推荐
相关产品推荐

