The timeline is often used in the front UI. Let’s take a look at the renderings:
Timeline features
1. The height in the list is uncertain, depending on the height of the item on the right. 2.
implementation
1. Set the border on the left by using the decoration attribute in the Container, so that the height of the timeline changes with item
Center(
child: Container(
width: 100,
height: 100,
decoration: BoxDecoration(
// set the border of the BoxDecoration. The border height is the height of the Container
border: Border(left: BorderSide(color: Colors.red)),
color: Color(0x11000000),)))Copy the code
The effect (the red line is the border to the left of the Container, which can be extended to timeline) :
Rewrite the paint method in BorderDirectional
So, the original Paint method in BorderDirectional, you can see that when you set different properties, you call different draw methods to do different things, so let’s do a new paint method to do the timeline
Parameters in the paint method
Canvas: This is the canvas. You can use this canvas to implement various effects. Rect: The size of Container
In our paint method, we use the UI design to draw circles and lines in the corresponding positions
@override
void paint(Canvas canvas, Rect rect, {TextDirection? textDirection, BoxShape shape = BoxShape.rectangle, BorderRadius? borderRadius}) {
if(position ! =1) {
canvas.drawLine(Offset(rect.left+margin + radius / 2, rect.top), Offset(rect.left +margin+ radius / 2, rect.bottom), _strokePaint());
canvas.drawCircle(Offset(rect.left +margin+ radius / 2, rect.top + radius * 2), radius, _fillPaint());
canvas.drawCircle(Offset(rect.left +margin+ radius / 2, rect.top + radius * 2), radius,_strokePaint());
} else {
canvas.drawLine(Offset(rect.left+margin + radius / 2, rect.top + radius * 2), Offset(rect.left+margin + radius / 2, rect.bottom), _strokePaint());
canvas.drawCircle(Offset(rect.left+margin + radius / 2, rect.top + radius * 2), radius, _fillPaint());
canvas.drawCircle(Offset(rect.left +margin+ radius / 2, rect.top + radius * 2), radius, _strokePaint());
canvas.drawCircle(Offset(rect.left +margin+ radius / 2, rect.top + radius * 2), radius / 2, _strokePaint()); }}Copy the code
The final result
Complete code
class BorderTimeLine extends BorderDirectional {
int position;
BorderTimeLine(this.position);
double radius = 10;
double margin= 20; Paint _paint = Paint() .. color = Color(0xFFDDDDDD)
..strokeWidth = 1;
@override
void paint(Canvas canvas, Rect rect, {TextDirection? textDirection, BoxShape shape = BoxShape.rectangle, BorderRadius? borderRadius}) {
if(position ! =0) {
canvas.drawLine(Offset(rect.left+margin + radius / 2, rect.top), Offset(rect.left +margin+ radius / 2, rect.bottom), _strokePaint());
canvas.drawCircle(Offset(rect.left +margin+ radius / 2, rect.top + radius * 2), radius, _fillPaint());
canvas.drawCircle(Offset(rect.left +margin+ radius / 2, rect.top + radius * 2), radius,_strokePaint());
} else {
canvas.drawLine(Offset(rect.left+margin + radius / 2, rect.top + radius * 2), Offset(rect.left+margin + radius / 2, rect.bottom), _strokePaint());
canvas.drawCircle(Offset(rect.left+margin + radius / 2, rect.top + radius * 2), radius, _fillPaint());
canvas.drawCircle(Offset(rect.left +margin+ radius / 2, rect.top + radius * 2), radius, _strokePaint());
canvas.drawCircle(Offset(rect.left +margin+ radius / 2, rect.top + radius * 2), radius / 2, _strokePaint());
}
}
Paint _fillPaint(){
_paint.color=Colors.white;
_paint.style=PaintingStyle.fill;
return _paint;
}
Paint _strokePaint(){
_paint.color=Color(0xFFDDDDDD);
_paint.style=PaintingStyle.stroke;
return_paint; }}Copy the code
Used within an item of the ListView
Widget _buildItem(BuildContext c, int i) {
return Container(
width: double.infinity,
padding: EdgeInsets.symmetric(horizontal: 20),
decoration: BoxDecoration(border: BorderTimeLine(i)),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [
Padding(padding: EdgeInsets.symmetric(vertical: 10)),
Divider(color: Colors.grey.shade300, thickness: 40),
Text("$i" * 6, style: TextStyle(color: Colors.black, fontSize: 16)),
Text("abc\n" * Random().nextInt(10)),
Padding(padding: EdgeInsets.symmetric(vertical: 10))))); }Copy the code