本文介绍了Flutter:创建时间轴UI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在尝试制作如下所示的时间轴用户界面:
但是我最终会执行以下操作:
我想增加Description文本的行数时,垂直分隔符的高度。我应该怎么做?
这是
I'm trying to make timeline UI like below:
But i end up doing following:
I want to increase the height of vertical Separator when no of lines of my Description text increases. How should i do that ?
Here is the link for the code
解决方案I like Osama's answer too but here's my quick custom implementation. It uses a CustomPainter to draw the lines.
import 'package:flutter/material.dart'; class Timeline extends StatelessWidget { const Timeline({ @required this.children, this.indicators, this.isLeftAligned = true, this.itemGap = 12.0, this.gutterSpacing = 4.0, this.padding = const EdgeInsets.all(8), this.controller, this.lineColor = Colors.grey, this.physics, this.shrinkWrap = true, this.primary = false, this.reverse = false, this.indicatorSize = 30.0, this.lineGap = 4.0, this.indicatorColor = Colors.blue, this.indicatorStyle = PaintingStyle.fill, this.strokeCap = StrokeCap.butt, this.strokeWidth = 2.0, this.style = PaintingStyle.stroke, }) : itemCount = children.length, assert(itemGap >= 0), assert(lineGap >= 0), assert(indicators == null || children.length == indicators.length); final List<Widget> children; final double itemGap; final double gutterSpacing; final List<Widget> indicators; final bool isLeftAligned; final EdgeInsets padding; final ScrollController controller; final int itemCount; final ScrollPhysics physics; final bool shrinkWrap; final bool primary; final bool reverse; final Color lineColor; final double lineGap; final double indicatorSize; final Color indicatorColor; final PaintingStyle indicatorStyle; final StrokeCap strokeCap; final double strokeWidth; final PaintingStyle style; @override Widget build(BuildContext context) { return ListView.separated( padding: padding, separatorBuilder: (_, __) => SizedBox(height: itemGap), physics: physics, shrinkWrap: shrinkWrap, itemCount: itemCount, controller: controller, reverse: reverse, primary: primary, itemBuilder: (context, index) { final child = children[index]; Widget indicator; if (indicators != null) { indicator = indicators[index]; } final isFirst = index == 0; final isLast = index == itemCount - 1; final timelineTile = <Widget>[ CustomPaint( foregroundPainter: _TimelinePainter( hideDefaultIndicator: indicator != null, lineColor: lineColor, indicatorColor: indicatorColor, indicatorSize: indicatorSize, indicatorStyle: indicatorStyle, isFirst: isFirst, isLast: isLast, lineGap: lineGap, strokeCap: strokeCap, strokeWidth: strokeWidth, style: style, itemGap: itemGap, ), child: SizedBox( height: double.infinity, width: indicatorSize, child: indicator, ), ), SizedBox(width: gutterSpacing), Expanded(child: child), ]; return IntrinsicHeight( child: Row( mainAxisAlignment: MainAxisAlignment.start, children: isLeftAligned ? timelineTile : timelineTile.reversed.toList(), ), ); }, ); } } class _TimelinePainter extends CustomPainter { _TimelinePainter({ @required this.hideDefaultIndicator, @required this.indicatorColor, @required this.indicatorStyle, @required this.indicatorSize, @required this.lineGap, @required this.strokeCap, @required this.strokeWidth, @required this.style, @required this.lineColor, @required this.isFirst, @required this.isLast, @required this.itemGap, }) : linePaint = Paint() ..color = lineColor ..strokeCap = strokeCap ..strokeWidth = strokeWidth ..style = style, circlePaint = Paint() ..color = indicatorColor ..style = indicatorStyle; final bool hideDefaultIndicator; final Color indicatorColor; final PaintingStyle indicatorStyle; final double indicatorSize; final double lineGap; final StrokeCap strokeCap; final double strokeWidth; final PaintingStyle style; final Color lineColor; final Paint linePaint; final Paint circlePaint; final bool isFirst; final bool isLast; final double itemGap; @override void paint(Canvas canvas, Size size) { final indicatorRadius = indicatorSize / 2; final halfItemGap = itemGap / 2; final indicatorMargin = indicatorRadius + lineGap; final top = size.topLeft(Offset(indicatorRadius, 0.0 - halfItemGap)); final centerTop = size.centerLeft( Offset(indicatorRadius, -indicatorMargin), ); final bottom = size.bottomLeft(Offset(indicatorRadius, 0.0 + halfItemGap)); final centerBottom = size.centerLeft( Offset(indicatorRadius, indicatorMargin), ); if (!isFirst) canvas.drawLine(top, centerTop, linePaint); if (!isLast) canvas.drawLine(centerBottom, bottom, linePaint); if (!hideDefaultIndicator) { final Offset offsetCenter = size.centerLeft(Offset(indicatorRadius, 0)); canvas.drawCircle(offsetCenter, indicatorRadius, circlePaint); } } @override bool shouldRepaint(CustomPainter oldDelegate) { return false; } }You'd call it something like:
Timeline( children: <Widget>[ Container(height: 100, color: color), Container(height: 50, color: color), Container(height: 200, color: color), Container(height: 100, color: color), ], indicators: <Widget>[ Icon(Icons.access_alarm), Icon(Icons.backup), Icon(Icons.accessibility_new), Icon(Icons.access_alarm), ], ),更多推荐
Flutter:创建时间轴UI
发布评论