You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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的高度扩展,修改步骤如下:

  1. 调整外层Row的对齐方式:

    • 将crossAxisAlignment: CrossAxisAlignment.center改为CrossAxisAlignment.stretch,让子组件自动撑满Row的高度
    • 移除mainAxisSize: MainAxisSize.min,让Row占用父容器的全部可用宽度
  2. 修改绿色Container的高度约束:

    • 移除包裹绿色Container的冗余Column
    • 给绿色Container添加height: double.infinity,让它自动填充Row的高度
  3. 优化右侧文本区域的布局:

    • 用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 02:25:02