SingleChildScrollView 内的水平滚动 ListView.builder - 包装内容高度
Posted
技术标签:
【中文标题】SingleChildScrollView 内的水平滚动 ListView.builder - 包装内容高度【英文标题】:Horizontal scrolling ListView.builder inside SingleChildScrollView - wrap content height 【发布时间】:2021-11-11 05:35:54 【问题描述】:我的布局是一个带有一些控件的表单小部件:
Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Form(
key: widget.addEventFormKey,
onChanged: () ,
child: Expanded(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(CustomResources.strings["add_event_category_label"], style: TextStyle(fontWeight: FontWeight.bold)),
/*some other widgets*/
Visibility(
child: Container(
height: 200.0,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: _attachments?.length,
itemBuilder: (context, index)
return Stack(
children: [
Container(
margin: EdgeInsets.fromLTRB(0, 0, 5, 0),
child: Stack(
children: [
ClipRRect(
child: Image.file(File(_attachments[index]), cacheWidth: 200),
borderRadius: BorderRadius.circular(8.0),
),
],
),
),
IconButton(
onPressed: ()
File(_attachments[index]).delete();
setState(() => _attachments.remove(_attachments[index]));
,
icon: Icon(FontAwesomeIcons.trash, color: Colors.white, size: 20),
padding: EdgeInsets.only(top: 4, left: 4),
constraints: BoxConstraints(),
),
],
);
,
),
),
visible: _attachments.length > 0,
),
Visibility(child: Padding(padding: EdgeInsets.fromLTRB(0, 18, 0, 0)),visible: _attachments.length > 0),
SizedBox(
child: RaisedButton(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24.0)),
onPressed: _attachments.length < 3 ? () => _pickImage() : null,
padding: EdgeInsets.all(12.0),
color: Colors.blue,
child: Text(CustomResources.strings["add_event_add_photo_button_label"], style: TextStyle(color: Colors.white))),
width: double.infinity,
),
],
),
),
),
),
],
);
有问题的部分是ListView.builder
显示水平滚动的图像列表。如您所见,图片将始终获得固定宽度(200)和未知高度,因为高度取决于图像纵横比。 ListView.builder
被 Container
包裹,所以现在它的高度为 200。
我想强制我的ListView.builder
扩展到子图像高度(它是水平滚动的单行 ListView),图像宽度始终为 200,其他小部件应放置在其下方,没有任何剩余空间。使用当前方法,如果图像高度 200,图像将被缩放(宽度/高度)。
我尝试用Expanded
小部件而不是Container
包装列表视图,但它抛出异常:
RenderFlex 子级具有非零 flex 但传入的高度约束 是无限的。
它说我仍然需要提供高度,但我不想这样做。如何解决?
【问题讨论】:
【参考方案1】:我认为 ListView.builder
无法做到这一点,因为在构建小部件树时它的动态项目高度是未知的。相反,我的缩略图小部件必须预先构建,并在构建后添加到Row
,并用SingleChildScrollView
包裹行以使其可滚动。所以,我的缩略图列表准备好放到我的Form
:
class AttachmentsListWidget extends StatelessWidget
const AttachmentsListWidget(
Key key,
@required this.items,
@required this.onAttachmentDeleted,
) : super(key: key);
final List<String> items;
final Function(String) onAttachmentDeleted;
@override
Widget build(BuildContext context)
var _thumbnailsScrollController = ScrollController();
final thumbnails = <Widget>[];
Widget thumbnailsWidget;
if (items.length > 0)
for (int i = 0; i < items.length; i++)
thumbnails.add(
AttachmentWidget(
attachment: items[i],
onDeleteClicked: (String attachment) => onAttachmentDeleted(attachment),
),
);
thumbnailsWidget = Container(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Scrollbar(
isAlwaysShown: true,
controller: _thumbnailsScrollController,
child: SingleChildScrollView(
controller: _thumbnailsScrollController,
scrollDirection: Axis.horizontal,
child: Row(
children: thumbnails,
crossAxisAlignment: CrossAxisAlignment.start,
),
),
),
],
),
);
else
thumbnailsWidget = Container();
return thumbnailsWidget;
(另外,添加了始终可见的滚动条)。
【讨论】:
【参考方案2】:如果您收到RenderFlex children have non-zero flex but incoming height constraints are unbounded.
,请尝试以下代码,希望对您有所帮助。在 Expanded() 小部件中添加您的 Column 并在您的代码中删除 SingleChildScrollView()
Expanded(
child: Column(
children:[
//Your Widgets
],
),
),
【讨论】:
您的意思是删除*** SingleChildScrollView 吗?我无法删除它,因为窗口内容需要可滚动 是的,但我认为当我们使用扩展小部件时,内容也可以滚动,只需尝试一下并告诉我。 不,它不可滚动。而且我认为***小部件与问题无关。问题是缩略图列表高度以上是关于SingleChildScrollView 内的水平滚动 ListView.builder - 包装内容高度的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Flutter 中自动滚动到 SingleChildScrollView 内的行的位置
SingleChildScrollView 内的水平滚动 ListView.builder - 包装内容高度
键盘溢出 * 像素。无法使用 SingleChildScrollView 或 ListView