Flutter报错:BoxConstraints的minHeight和maxHeight为NaN问题求助
问题分析与解决方案
错误原因
你遇到的BoxConstraints has NaN values错误,核心问题是不必要的嵌套滚动组件导致约束冲突:
VerticalCardPager本身就是封装好的垂直滚动卡片组件,会自行处理列表展示与滚动逻辑。- 你在
Expanded内部用ListView.builder包裹它,且每个item都重新创建了包含所有英雄的VerticalCardPager,这不仅完全冗余,还让VerticalCardPager无法从父组件获取有效高度约束,最终计算出NaN的高度值。
修复后的代码
移除多余的ListView.builder,直接使用VerticalCardPager展示所有英雄卡片,并添加点击跳转逻辑:
import 'package:flutter/material.dart'; import 'package:vertical_card_pager/vertical_card_pager.dart'; import 'models/hero_model.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, title: 'Valorant Agents', theme: ThemeData( primarySwatch: Colors.blue, ), home: const MyHomePage(), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({Key? key}) : super(key: key); @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { alert(String msg) { ScaffoldMessenger.of(context).showSnackBar(SnackBar( content: Text(msg), action: SnackBarAction( label: "FECHAR", onPressed: () => ScaffoldMessenger.of(context).hideCurrentSnackBar(), ), )); } final List<HeroModel> heros = [ HeroModel("JETT", "images/jett_valo.gif"), HeroModel("KILLJOY", "images/killjoy_valo.gif"), HeroModel("SAGE", "images/sage_valo.gif"), HeroModel("SOVA", "images/sova_valo.gif"), HeroModel("VIPER", "images/viper_valo.gif"), HeroModel("RAZE", "images/raze_valo.gif"), HeroModel("YORU", "images/yoru_valo.gif"), HeroModel("BREACH", "images/breach_valo.gif"), HeroModel("ASTRA", "images/astra_valo.gif"), HeroModel("CYPHER", "images/cypher_valo.gif"), HeroModel("OMEN", "images/omen_valo.gif"), HeroModel("PHOENIX", "images/phoenix_valo.gif"), HeroModel("SKYE", "images/skye_valo.gif"), ]; // 跳转详情页的方法 void _navigateToHeroDetail(HeroModel hero) { // 替换为你的详情页路由逻辑 Navigator.push( context, MaterialPageRoute( builder: (context) => HeroDetailPage(hero: hero), ), ); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.black38, body: SafeArea( child: Column( children: [ SizedBox( width: double.infinity, height: 70, child: Padding( padding: const EdgeInsets.symmetric(vertical: 5), child: Center( child: Image.asset( "images/logo.png", fit: BoxFit.cover, ), ), ), ), // 直接使用VerticalCardPager,移除多余的ListView.builder Expanded( child: VerticalCardPager( titles: heros.map((hero) => hero.title).toList(), images: heros.map((hero) { return GestureDetector( // 添加点击事件跳转详情页 onTap: () => _navigateToHeroDetail(hero), child: Hero( tag: hero.title, child: ClipRRect( borderRadius: BorderRadius.circular(20.0), child: Image.asset( hero.image, fit: BoxFit.cover, ), ), ), ); }).toList(), textStyle: const TextStyle( color: Colors.white, fontWeight: FontWeight.bold), initialPage: 2, align: ALIGN.CENTER, ), ) ], ), ), ); } } // 示例详情页组件,根据需求修改 class HeroDetailPage extends StatelessWidget { final HeroModel hero; const HeroDetailPage({super.key, required this.hero}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text(hero.title)), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Hero( tag: hero.title, child: Image.asset(hero.image), ), const SizedBox(height: 20), Text(hero.title, style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold)), ], ), ), ); } }
关键修改点
- 移除冗余的
ListView.builder:VerticalCardPager本身已实现垂直滚动卡片列表功能,无需额外嵌套ListView。 - 添加点击跳转逻辑:用
GestureDetector包裹每个英雄的Hero组件,绑定onTap事件触发详情页跳转。 - 优化数据映射:使用
map方法替代循环生成列表,代码更简洁。
内容的提问来源于stack exchange,提问作者Mikael David
相关产品推荐
相关产品推荐

