需求
电商网站常会用到的物流时间线
方法一
利用Stack做,一层渲染,一层渲染列表和表示状态的圆点
注意点1:因为Stack的高度约束是0~infinity,默认子Container高度为0,设置top、bottom后才能显示
注意点2:text需要包裹Expanded,否则无法换行
注意点3:最外层要包裹Column,Stack高度会随子集变化而变化,否则高度会占满整个屏幕
import 'package:flutter/material.dart';
class DateLine extends StatelessWidget {
final List textList = [
'[收货地址]浙江省宁波市鄞州区 中河街道 甬兴西路甬兴新村 185****4512',
'您的快件已暂存至宁波市甬兴新村菜鸟驿站,您的快件已暂存至宁波市甬兴新村菜鸟驿站,请及时取件有问题请联系请及时取件有问题请联系',
'[宁波市]宁波市鄞州区的李XXXXXX[]正在派件',
'[宁波市]快件已到达宁波鄞州区',
'[宁波市]快件已到达宁波鄞州区',
'商品已下单',
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('时间线'),),
body: Column(children: [
Padding(padding: EdgeInsets.all(15),
child: Stack(children: [
//线
Positioned(left: 10,top: 10,bottom: 0,//重点,因为Stack的高度约束是0~infinity,默认子Container高度为0,设置top、bottom后才能显示
child: Container(width: 1,color: Colors.red,),),
//列表
Column(crossAxisAlignment: CrossAxisAlignment.start,children: List.generate(6, (index){
return Container(padding: EdgeInsets.only(bottom: 20),child: Column(children: [
Row(crossAxisAlignment: CrossAxisAlignment.start,children: [
//状态圆点
Container(width: 20,height: 20,alignment: Alignment.center,
child: Container(width: 12,height: 12,decoration: BoxDecoration(borderRadius: BorderRadius.circular(6),color: Colors.yellow),),),
SizedBox(width: 5,),
//文字信息
Expanded(child: Text(this.textList[index],style: TextStyle(color: Colors.grey,fontSize: 14),)),
],),
SizedBox(height: 5,),
Row(children: [
SizedBox(width: 25,),
Text('2021-12-28 13:56:25',style: TextStyle(color: Colors.grey,fontSize: 12),)
],)
],),);
}),)
],)
),
],),
);
}
}
效果
待解决问题
最后一个子集有线条露出
方法一改
解决最后一个子集有线条露出问题。
为最后一个子集创建Stack,遮盖线条
import 'package:flutter/material.dart';
class DateLine extends StatelessWidget {
final List textList = [
'[收货地址]浙江省宁波市鄞州区 中河街道 甬兴西路甬兴新村 185****4512',
'您的快件已暂存至宁波市甬兴新村菜鸟驿站,您的快件已暂存至宁波市甬兴新村菜鸟驿站,请及时取件有问题请联系请及时取件有问题请联系',
'[宁波市]宁波市鄞州区的李XXXXXX[]正在派件',
'[宁波市]快件已到达宁波鄞州区',
'[宁波市]快件已到达宁波鄞州区',
'商品已下单',
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('时间线'),),
body: Container(color: Colors.white,
child: Column(children: [
Padding(padding: EdgeInsets.all(15),
child: Stack(children: [
//线
Positioned(left: 10,top: 10,bottom: 0,//重点,因为Stack的高度约束是0~infinity,默认子Container高度为0,设置top、bottom后才能显示
child: Container(width: 1,color: Colors.red,),),
//列表
Column(crossAxisAlignment: CrossAxisAlignment.start,children: List.generate(this.textList.length, (index){
if(index == this.textList.length - 1){
//最后一个节点
return Stack(children: [
Container(padding: EdgeInsets.only(bottom: 20),child: Column(children: [
Row(crossAxisAlignment: CrossAxisAlignment.start,children: [
//状态圆点
Container(width: 20,height: 20,alignment: Alignment.center,
child: Container(width: 8,height: 8,decoration: BoxDecoration(borderRadius: BorderRadius.circular(6),color: Colors.yellow),),),
SizedBox(width: 5,),
//文字信息
Expanded(child: Text(this.textList[index],style: TextStyle(color: Colors.grey,fontSize: 14),)),
],),
SizedBox(height: 5,),
Row(children: [
SizedBox(width: 25,),
Text('2021-12-28 13:56:25',style: TextStyle(color: Colors.grey,fontSize: 12),)
],)
],),),
Positioned(top: 14,bottom: 0,child: Container(width: 20,color: Colors.white,))
],);
}else{
return Container(padding: EdgeInsets.only(bottom: 20),child: Column(children: [
Row(crossAxisAlignment: CrossAxisAlignment.start,children: [
//状态圆点
Container(width: 20,height: 20,alignment: Alignment.center,
child: Container(width: 8,height: 8,decoration: BoxDecoration(borderRadius: BorderRadius.circular(6),color: Colors.yellow),),),
SizedBox(width: 5,),
//文字信息
Expanded(child: Text(this.textList[index],style: TextStyle(color: Colors.grey,fontSize: 14),)),
],),
SizedBox(height: 5,),
Row(children: [
SizedBox(width: 25,),
Text('2021-12-28 13:56:25',style: TextStyle(color: Colors.grey,fontSize: 12),)
],)
],),);
}
}),)
],)
),
],),
),
);
}
}
最终效果
方法二
利用边框做线,Stack绘制状态圆点
import 'package:flutter/material.dart';
class DateLine extends StatelessWidget {
final List textList = [
'[收货地址]浙江省宁波市鄞州区 中河街道 甬兴西路甬兴新村 185****4512',
'您的快件已暂存至宁波市甬兴新村菜鸟驿站,您的快件已暂存至宁波市甬兴新村菜鸟驿站,请及时取件有问题请联系请及时取件有问题请联系',
'[宁波市]宁波市鄞州区的李XXXXXX[]正在派件',
'[宁波市]快件已到达宁波鄞州区',
'[宁波市]快件已到达宁波鄞州区',
'商品已下单',
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('时间线'),),
body: Container(color: Colors.white,
child: Column(children: List.generate(this.textList.length, (index){
return Container(width: double.infinity,child: Stack(children: [
Container(padding: EdgeInsets.only(left: 20,bottom: 25),margin: EdgeInsets.only(left: 20),
//绘制边框线,最后一个不绘制
decoration: BoxDecoration(border: Border(left: BorderSide(color: index == this.textList.length - 1 ? Colors.white : Colors.blue,width: 1))),
child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: [
Text(this.textList[index],style: TextStyle(color: Colors.grey,fontSize: 12),),
SizedBox(width: 25,),
Text('2021-12-28 13:56:25',style: TextStyle(color: Colors.grey,fontSize: 10),)
],),
),
//状态圆点
Positioned(left: 12.5,top: 0,
child: Container(width: 15,height: 15,decoration: BoxDecoration(borderRadius: BorderRadius.circular(20),color: Colors.yellow),),
),
],),);
}),),
)
);
}
}
效果
待解决问题
当圆点直径和文字的高度一致时,效果最好
当圆点直径小于文字的高度,如果不给圆点加top,与文字垂直上无法对其,如果加上top,第一个圆点上线条会冒尖,最后一个圆点上会有一部分空缺
当圆点直径大于文字的高度,与文字无法对其
请大佬赐教。