Flutter跨列对齐组件:实现高度可变的时间线布局
Flutter 动态高度时间线实现方案
核心思路
通过Row+Column+IntrinsicHeight的组合,实现图标与文本对齐,同时让图标间的连线高度随地点文本行数动态调整。
步骤实现
1. 定义数据模型
先创建时间线节点的数据类,统一管理每个节点的时间、图标和地点信息:
class TimelineNode { final String time; final IconData icon; final String location; TimelineNode({ required this.time, required this.icon, required this.location, }); }
2. 构建时间线组件
使用ListView.builder渲染节点列表,每个节点分为三个区域:时间文本、图标+连线、地点文本:
import 'package:flutter/material.dart'; class TimelineView extends StatelessWidget { // 模拟数据 final List<TimelineNode> nodes = [ TimelineNode( time: '16:03', icon: Icons.radio_button_checked, location: 'Barbarossaplatz', ), TimelineNode( time: '', icon: Icons.location_on, location: 'Efferen', ), TimelineNode( time: '16:15', icon: Icons.location_on, location: 'Hauptbahnhof - 多行文本测试,验证连线高度随文本行数动态变化', ), ]; TimelineView({super.key}); @override Widget build(BuildContext context) { return ListView.builder( itemCount: nodes.length, itemBuilder: (context, index) { final node = nodes[index]; return Padding( padding: const EdgeInsets.only(bottom: 8.0), child: Row( // 图标与文本顶部对齐,若需居中可改为CrossAxisAlignment.center crossAxisAlignment: CrossAxisAlignment.start, children: [ // 时间区域:固定宽度+右对齐,保证时间排版整齐 SizedBox( width: 60, child: Text( node.time, textAlign: TextAlign.right, style: const TextStyle(fontSize: 14), ), ), const SizedBox(width: 12), // 图标与连线区域 IntrinsicHeight( child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon( node.icon, size: 20, color: Colors.blue, ), // 最后一个节点不显示连线 if (index != nodes.length - 1) Expanded( child: Container( width: 2, color: Colors.grey.shade400, margin: const EdgeInsets.only(left: 8), // 连线对齐图标中心 ), ), ], ), ), const SizedBox(width: 8), // 地点文本区域:自适应宽度 Expanded( child: Text( node.location, style: const TextStyle(fontSize: 14), ), ), ], ), ); }, ); } }
关键细节说明
IntrinsicHeight:强制图标区域的高度与当前节点的最高子元素(地点文本)保持一致,让Expanded包裹的连线自动填充图标下方的剩余空间,实现动态高度。- 时间区域固定宽度并右对齐,确保所有时间文本垂直对齐,提升视觉整洁度。
- 连线通过
margin偏移对齐图标中心,优化视觉连贯性。
内容的提问来源于stack exchange,提问作者DeKekem
相关产品推荐
相关产品推荐

