Flutter左侧绿色Container高度无法匹配Row问题求助
问题:让左侧绿色Container高度跟随所在Row的高度
我希望左侧的绿色Container高度能跟随所在Row的高度,已经尝试修改代码两天但仍未解决,恳请各位帮忙。
主组件代码
class DaftarAnySelectMultiple<T> extends Stateful Widget { final String title; final String? hintSearch; final List<T> data; final void Function(List<T> data)? onSelected; final bool Function(String search, T data)? onSearchFn; final Widget Function(T data) itemBuilder; final String? textButton; const DaftarAnySelectMultiple({ super.key, required this.title, this.hintSearch, this.onSelected, required this.data, this.onSearchFn, required this.itemBuilder, this.textButton, }); @override State<DaftarAnySelectMultiple> createState() = _DaftarAnySelectMultipleState<T>(); } class _DaftarAnySelectMultipleState<T> extends State<DaftarAnySelectMultiple<T>> { TextEditingController searchC = TextEditingController(); List<bool> isCheckedList = []; List<T> get displayData { if (searchC.text.isEmpty || widget.onSearchFn == null) return widget.data; List<T> willDisplay = []; for (var e in widget.data) { bool matched = widget.onSearchFn!(searchC.text, e); if (matched) { willDisplay.add(e); } } return willDisplay; } @override void initState() { super.initState(); // 初始化选中状态列表 isCheckedList = List.generate(displayData.length, (index) => false); } @override Widget build(BuildContext context) { return SafeArea( child: Scaffold( body: Column( children: [ HeaderBab(title: widget.title), if (widget.onSearchFn != null) ...[ Padding( padding: const EdgeInsets.only(top: 20.0, bottom: 20), child: CustomSearchWidget( hintText: widget.hintSearch, onChanged: (_) { setState(() {}); }, textEditingController: searchC, ), ), ], Expanded( child: ListView.builder( shrinkWrap: true, padding: widget.onSearchFn == null ? const EdgeInsets.only(top: 4) : null, itemCount: displayData.length, itemBuilder: (context, index) { return IntrinsicHeight( child: Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(6), border: Border.all(color: primaryGreen), ), margin: const EdgeInsets.only(bottom: 4, left: 8, right: 8), child: Row( children: [ widget.itemBuilder(displayData[index]), Spacer(), Padding( padding: const EdgeInsets.symmetric(vertical: 4), child: InkWell( child: Container( decoration: BoxDecoration( shape: BoxShape.rectangle, border: Border.all( color: isCheckedList[index] ? primaryGreen : primaryBlue), ), height: 25, width: 25, child: Center( child: isCheckedList[index] ? const Icon( Icons.check_rounded, color: primaryGreen, size: 25, ) : Container(), ), ), onTap: () { setState(() { isCheckedList[index] = !isCheckedList[index]; }); }, ), ), const SizedBox(width: 10) ], ), ), ); }, ), ) ], ), bottomNavigationBar: BottomButtonPrimary( "SIMPAN", onPress: () { List<T> selectedMultiple = []; for (int i = 0; i < isCheckedList.length; i++) { if (isCheckedList[i]) { selectedMultiple.add(displayData[i]); } } widget.onSelected?.call(selectedMultiple); Nav.back(data: "refresh"); }, ), ), ); } }
itemBuilder实现(CustomBox)
import 'package:flutter/material.dart'; import 'package:ocs_form/config/colors.dart'; import 'package:ocs_form/config/constants.dart'; class CustomBox extends Stateful Widget { const CustomBox({ Key? key, required this.dataAny, required this.index, }) : super(key: key); final List dataAny; final int index; @override // ignore: library_private_types_in_public_api _CustomBoxState createState() => _CustomBoxState(); } class _CustomBoxState extends State<CustomBox> { @override Widget build(BuildContext context) { return Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( width: 50, decoration: BoxDecoration( borderRadius: BorderRadius.only( topLeft: Radius.circular(6), bottomLeft: Radius.circular(6), ), boxShadow: const [ BoxShadow(color: Colors.green), BoxShadow( color: Colors.white70, spreadRadius: -5.0, blurRadius: 20.0, ), ], ), child: Center( child: Text( "${widget.dataAny[widget.index][0]}", style: const TextStyle( fontWeight: FontWeight.bold, fontSize: 20, color: black87, ), ), ), ), ], ), const SizedBox(width: 4), Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Container( width: MediaQuery.of(context).size.width - 130, child: Text( "${widget.dataAny[widget.index][1]}", style: const TextStyle( fontWeight: FontWeight.bold, fontSize: 20, color: black45, ), ), ), ], ) ], ); } }
解决方案
问题根源在于CustomBox的嵌套布局限制了绿色Container的高度扩展,修改步骤如下:
调整外层Row的对齐方式:
- 将
crossAxisAlignment: CrossAxisAlignment.center改为CrossAxisAlignment.stretch,让子组件自动撑满Row的高度 - 移除
mainAxisSize: MainAxisSize.min,让Row占用父容器的全部可用宽度
- 将
修改绿色Container的高度约束:
- 移除包裹绿色Container的冗余
Column - 给绿色Container添加
height: double.infinity,让它自动填充Row的高度
- 移除包裹绿色Container的冗余
优化右侧文本区域的布局:
- 用
Expanded包裹右侧Column,避免文本过长导致溢出 - 保持
mainAxisAlignment: MainAxisAlignment.center让文本垂直居中
- 用
修改后的CustomBox代码:
class _CustomBoxState extends State<CustomBox> { @override Widget build(BuildContext context) { return Row( crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisAlignment: MainAxisAlignment.start, children: [ Container( width: 50, height: double.infinity, decoration: BoxDecoration( borderRadius: BorderRadius.only( topLeft: Radius.circular(6), bottomLeft: Radius.circular(6), ), boxShadow: const [ BoxShadow(color: Colors.green), BoxShadow( color: Colors.white70, spreadRadius: -5.0, blurRadius: 20.0, ), ], ), child: Center( child: Text( "${widget.dataAny[widget.index][0]}", style: const TextStyle( fontWeight: FontWeight.bold, fontSize: 20, color: black87, ), ), ), ), const SizedBox(width: 4), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ Text( "${widget.dataAny[widget.index][1]}", style: const TextStyle( fontWeight: FontWeight.bold, fontSize: 20, color: black45, ), ), ], ), ) ], ); } }
主组件中的IntrinsicHeight可以保留,它会让外层Container的高度自适应Row内容,配合上述修改,绿色Container就能完美跟随所在Row的高度了。
内容的提问来源于stack exchange,提问作者Nur Fajar Ismail
相关产品推荐
相关产品推荐

