ListView.Builder中自定义双TextField组件需指定尺寸才显示问题
问题解决:ListView.Builder中自定义Widget不显示的问题
问题根源
你的自定义Widget里用Expanded包裹了Column的子项,但ListView.builder的子项需要自身能确定尺寸。Expanded依赖父级有明确的尺寸约束才能计算剩余空间,而ListView的滚动容器没有固定高度,导致Column无法正确布局,最终组件完全不显示。
修复方案
- 移除Column中的Expanded组件:不需要让子项强行占满剩余空间,让它们根据自身内容自适应高度即可。
- 保留Row内的Expanded:Row中的Expanded用于让TextFormField占满Row的可用宽度,这是合理的——因为Row的高度由PopupMenuButton的固定高度(50)确定,能给TextFormField提供明确的高度约束。
- 让TextField自适应高度:第二个TextField设置了
maxLines: null,本身就能根据内容自动换行和调整高度,不需要用Expanded包裹。 - 修复titre变量的无效问题:当前Widget是无状态的,titre变量每次build都会被重置,建议通过回调函数将输入值传递给父组件,或者将该Widget改为StatefulWidget。
修改后的代码
import 'package:flutter/material.dart'; import 'functions/cardsFunctions.dart'; Widget concept(String type, String title, String description, int index, Function setState, String id) { return Container( padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), // 可选:添加内边距优化布局 child: Column( mainAxisSize: MainAxisSize.min, // 让Column仅包裹子项所需高度 children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[ Expanded( child: TextFormField( initialValue: title, // 可选:传入初始值 textAlign: TextAlign.justify, enableSuggestions: true, maxLength: 75, onChanged: (String text) { // 通过回调传递值给父组件,替代局部变量titre setState(() {}); }, ), ), const SizedBox(width: 8), // 可选:添加间距优化布局 SizedBox( height: 50, child: PopupMenuButton( offset: const Offset(-50, 0), itemBuilder: (context) => [ PopupMenuItem( onTap: () { // 注意:获取最新输入值需从父组件状态中取,不能用局部变量titre updateCard('hello', title, id); model(); }, child: const ListTile( leading: Icon(Icons.update_rounded), title: Text('Update'), ), ), PopupMenuItem( onTap: () { deleteCard(id, index); }, child: const ListTile( leading: Icon(Icons.delete_forever_rounded), title: Text('Delete'), ), ), ], ), ), ], ), const SizedBox(height: 10), TextField( controller: TextEditingController(text: description), // 可选:传入初始值 maxLines: null, textAlign: TextAlign.justify, enableSuggestions: true, maxLength: 2000, decoration: const InputDecoration( hintText: 'What is it ?', border: InputBorder.none, ), ), ], ), ); }
额外说明
- 添加
mainAxisSize: MainAxisSize.min到Column,确保Column只占用子项所需的最小高度,这在ListView的子项中非常关键。 - 局部变量
titre无法正确保存输入值,因为Widget每次重建都会重置该变量,建议通过回调函数将输入值同步到父组件的状态中,或者将concept改为StatefulWidget来管理输入状态。
内容的提问来源于stack exchange,提问作者Kerby Elpenord
相关产品推荐
相关产品推荐

