Flutter登录触发Uncaught Error: Cannot hit test a render box with no size求助
解决Flutter中AlertDialog内ListView的尺寸报错问题
问题描述
点击登录按钮后,应用本应弹出对话框展示数据库中的所有用户,但触发报错:Uncaught Error: Cannot hit test a render box with no size,尝试使用shrinkWrap属性未解决问题。
报错原因
AlertDialog的content使用了Column并设置mainAxisSize: MainAxisSize.min,此时Column的高度由子组件自身尺寸决定。但其中的ListView被Expanded包裹,Expanded会强制子组件占据剩余空间,而MainAxisSize.min的Column无法提供足够的高度约束,导致ListView无法确定自身尺寸,引发报错。即使给ListView添加shrinkWrap: true,也会因为Expanded的强制填充要求产生冲突,无法解决问题。
解决方案
方案1:给ListView设置固定高度
用SizedBox包裹ListView,明确指定高度,让ListView有确定的尺寸约束:
showDialog( context: context, builder: (BuildContext context) => AlertDialog( title: Text('Szia, ${currentUser.name}!'), content: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('A te ID-d ${currentUser.id}'), SizedBox(height: 8), Text('A felhasznalok:'), // 添加固定高度的SizedBox SizedBox( height: 200, // 根据需求调整高度 child: ListView.builder( itemCount: persons.length, itemBuilder: (context, index) { return Text(persons[index].name); }, ), ), ], ), ), );
方案2:移除Expanded并启用shrinkWrap
如果用户列表内容不多,不需要滚动,可以移除Expanded,给ListView设置shrinkWrap: true和physics: NeverScrollableScrollPhysics():
showDialog( context: context, builder: (BuildContext context) => AlertDialog( title: Text('Szia, ${currentUser.name}!'), content: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('A te ID-d ${currentUser.id}'), SizedBox(height: 8), Text('A felhasznalok:'), ListView.builder( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), // 禁止滚动,让Column适应内容高度 itemCount: persons.length, itemBuilder: (context, index) { return Text(persons[index].name); }, ), ], ), ), );
如果内容较多需要滚动,建议使用方案1,避免对话框内容过长超出屏幕范围。
修改后的完整代码
import 'package:flutter/material.dart'; import 'api.dart'; import 'person.dart'; class MainScreen extends StatefulWidget { const MainScreen({Key? key, required person}) : super(key: key); @override _MainScreenState createState() => _MainScreenState(); } class _MainScreenState extends State<MainScreen> { TextEditingController _usernameController = TextEditingController(); TextEditingController _passwordController = TextEditingController(); Future<List<Person>> _futurePersons = Api.getPersons(); void _login() async { String username = _usernameController.text; String password = _passwordController.text; try { final persons = await _futurePersons; final currentUserIndex = persons.indexWhere( (person) => person.name == username, ); final currentUser = currentUserIndex > -1 ? persons[currentUserIndex] : null; if (currentUser != null) { showDialog( context: context, builder: (BuildContext context) => AlertDialog( title: Text('Szia, ${currentUser.name}!'), content: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('A te ID-d ${currentUser.id}'), SizedBox(height: 8), Text('A felhasznalok:'), // 使用方案1:固定高度的ListView SizedBox( height: 200, child: ListView.builder( itemCount: persons.length, itemBuilder: (context, index) { return Padding( padding: EdgeInsets.symmetric(vertical: 4), child: Text(persons[index].name), ); }, ), ), ], ), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: Text('Bezár'), ), ], ), ); } else { showDialog( context: context, builder: (BuildContext context) => AlertDialog( title: Text('Hiba'), content: Text('Nincs ilyen nevu felhasznalo'), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: Text('Bezár'), ), ], ), ); } } catch (e) { print('Hiba a felhasznalo keresese kozben: $e'); showDialog( context: context, builder: (BuildContext context) => AlertDialog( title: Text('Hiba'), content: Text('Nem sikerult megtalalni a felhasznalot'), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: Text('Bezár'), ), ], ), ); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('teszt'), ), body: Padding( padding: EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ TextFormField( controller: _usernameController, decoration: InputDecoration( hintText: 'Felhasznalo nev', ), ), SizedBox(height: 16.0), TextFormField( controller: _passwordController, obscureText: true, decoration: InputDecoration( hintText: 'Jelszo', ), ), SizedBox(height: 16.0), ElevatedButton( onPressed: _login, child: Text('Belepes'), ), ], ), ), ); } }
内容的提问来源于stack exchange,提问作者laccc___
相关产品推荐
相关产品推荐

