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

Flutter问题:如何让垂直虚线自适应右侧列表高度?

解决Flutter垂直虚线动态适配列表高度问题

问题原因

Row的布局逻辑是横向排列,子组件不能直接设置无限高度——Row自身的高度由内部最高子组件决定,直接给CustomPaint指定double.infinity会破坏布局约束,引发报错。

解决方案

方法1:用IntrinsicHeight统一Row内子组件高度

通过IntrinsicHeight包裹Row,强制所有子组件高度匹配右侧列表的实际高度,让虚线自动适配:

var widgetsFinal = <Widget>[
  const MenuBar(),
  Padding(
    padding: const EdgeInsets.only(left: 50),
    child: IntrinsicHeight( // 新增:统一Row内所有子组件高度
      child: Row(
        children: [
          CustomPaint(
            painter: VerticalDottedLinePainter(
              color: const Color.fromRGBO(135, 235, 240, 1),
              strokeWidth: 2,
              gapSize: 30,
            ),
            size: const Size(2, double.infinity), // 现在会被约束为Row的实际高度
          ),
          const SizedBox(width: 10),
          Expanded(
            flex: 2,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.start,
              children: drinkWidgets,
            ),
          ),
        ],
      ),
    ),
  ),
];

return Scaffold(
  body: Stack(
    children: <Widget>[
      SingleChildScrollView(
        child: Container(color: Colors.black, child: Column(children: widgetsFinal)),
      ),
    ],
  ),
);

方法2:修改VerticalDottedLinePainter适配父组件约束

如果不想用IntrinsicHeight,可以调整Painter逻辑,让它根据父组件的实际约束绘制,无需手动传入高度:

// 修改后的Painter类
class VerticalDottedLinePainter extends CustomPainter {
  final Color color;
  final double strokeWidth;
  final double gapSize;

  VerticalDottedLinePainter({
    required this.color,
    required this.strokeWidth,
    required this.gapSize,
  });

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = color
      ..strokeWidth = strokeWidth
      ..style = PaintingStyle.stroke;

    double currentY = 0;
    final dashLength = gapSize; // 可根据需求调整线段长度
    while (currentY < size.height) {
      canvas.drawLine(
        Offset(size.width / 2, currentY),
        Offset(size.width / 2, currentY + dashLength),
        paint,
      );
      currentY += dashLength + gapSize;
    }
  }

  @override
  bool shouldRepaint(covariant VerticalDottedLinePainter oldDelegate) {
    return oldDelegate.color != color ||
        oldDelegate.strokeWidth != strokeWidth ||
        oldDelegate.gapSize != gapSize;
  }
}

对应布局修改:

Padding(
  padding: const EdgeInsets.only(left: 50),
  child: IntrinsicHeight(
    child: Row(
      children: [
        SizedBox(
          width: 2, // 固定虚线宽度
          child: CustomPaint(
            painter: VerticalDottedLinePainter(
              color: const Color.fromRGBO(135, 235, 240, 1),
              strokeWidth: 2,
              gapSize: 30,
            ),
            // 不再手动设置size,由父组件约束自动适配高度
          ),
        ),
        const SizedBox(width: 10),
        Expanded(
          flex: 2,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            children: drinkWidgets,
          ),
        ),
      ],
    ),
  ),
),

注意事项

IntrinsicHeight会带来轻微性能开销(需预先计算所有子组件高度),但对于常规长度的列表可忽略;如果是超大型列表,可考虑用LayoutBuilder结合右侧列表的key获取高度,再传递给虚线组件。

内容的提问来源于stack exchange,提问作者Joe Nordling

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 04:15:21